gpt4 book ai didi

python - 在阅读之前懒惰地过滤文件

转载 作者:太空狗 更新时间:2023-10-30 01:34:43 24 4
gpt4 key购买 nike

假设我有一个大文件,其中包含一些我希望忽略的行,以及一个接受文件对象的函数 (file_function)。我能否返回一个新的文件对象,其行满足某些条件而不先读取整个文件,这个惰性是重要的部分。

注意:我可以只保存一个忽略这些行的临时文件,但这并不理想。

例如,假设我有一个 csv 文件(带有错误行):

1,2
ooops
3,4

第一次尝试是创建新的文件对象(使用与文件相同的方法)并覆盖readline:

class FileWithoutCondition(file):
def __init__(self, f, condition):
self.f = f
self.condition = condition
def readline(self):
while True:
x = self.f.readline()
if self.condition(x):
return x

这在 file_name 仅使用 readline 时有效...但如果它需要一些其他功能则无效。

with ('file_name', 'r') as f:
f1 = FileWithoutOoops(f, lambda x: x != 'ooops\n')
result = file_function(f1)

使用 StringIO 的解决方案可能有效,但我似乎做不到。

理想情况下,我们应该假设 file_function 是一个黑盒函数,具体来说,我不能仅仅调整它来接受一个生成器(但也许我可以将一个生成器调整为类文件?)。< br/>是否有一种标准方法可以对通用文件进行这种惰性(略读)读取?

注意:这个问题的激励示例是 this pandas question ,只有 readline 不足以让 pd.read_csv 工作...

最佳答案

将 map-reduce 方法与现有的 Python 工具结合使用。在此示例中,我使用正则表达式来匹配以字符串 GET/index 开头的行,但您可以使用符合您要求的任何条件:

import re
from collections import defaultdict

pattern = re.compile(r'GET /index\(.*\).html')

# define FILE appropriately.
# map
# the condition here serves to filter lines that can not match.
matches = (pattern.search(line) for line in file(FILE, "rb") if 'GET' in line)
mapp = (match.group(1) for match in matches if match)

# now reduce, lazy:
count = defaultdict(int)
for request in mapp:
count[request] += 1

这会在我的笔记本电脑上几秒钟内扫描一个 >6GB 的文件。您可以进一步将文件分成 block 并将它们提供给线程或进程。使用 mmap 我不推荐,除非你有足够的内存来映射整个文件(它不支持窗口化)。

关于python - 在阅读之前懒惰地过滤文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15090685/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com