我有一个大文本文件(500 万到 1000 万行)。每行有 10 到 5,000 个字母数字项目,它们之间用空格或逗号分隔。每行以换行符结束。行数在运行前是已知的,并且文本文件在运行时不会改变。
每次运行代码,都会传递 50-200个搜索列表,每个搜索列表包含 2-10 个项目(单词)。对于这些搜索列表中的每一个,我想在文本文件中找到x行,其中至少包含该列表中的一项。行数x范围为 5-10 行,并在运行时设置。匹配不区分大小写并且必须在单词边界上精确(例如,“foo”匹配“,foo”但不匹配“foobar”)。
每个搜索列表都有以下三种搜索顺序策略之一:
正常。从第一行开始,按连续顺序逐行搜索,直到找到x行或到达最后一行。
随机。从文本文件中随机选择行。继续前进,直到找到x行或完成对每一行的搜索。
桶范围。首先搜索最高优先级范围的行,然后是下一个最高优先级范围,然后是下一个,等等。例如,搜索范围优先级可能是首先查看行 1,000,000 到 1,499,999,然后是行 0 到 999,999,然后是行1,500,000 到 2,199,999 等。可以有 3 到 20 个桶,每个桶涵盖 100,000 到 5,000,000 行的范围。桶数和行号范围在运行时给出。在每个范围内,连续搜索。搜索直到找到x行或到达最后一个桶的末尾。
这是我为“正常搜索”编写的内容[此测试代码检查文件末尾的所有行,而不会在x行之后停止;在最终版本中,在为搜索列表找到x 个匹配项后,它会停止并继续前进到下一个搜索列表]:
import re
textFile = "bigTextFile.txt"
searchItems = ["foo","bar","anotherfoo","anotherbar","etc"]
searchStrategy = "normal" #could be "normal", "random", "bucket"; this code is just for "normal"
results = []
with open(textFile) as inFile:
for line in inFile:
regex = re.compile('(' + '|'.join('\\b'+item+'\\b' for item in searchItems) +')', re.IGNORECASE)
match = regex.search(line)
if match is not None:
analysisResult = analyze_the_match(line)
results.append(analysisResult)
此“正常搜索”代码有效。在我尝试过的方法中,它似乎是最快的,但我是 Python 新手,我想一定有更好的方法(速度/效率)来做到这一点。
[根据评论更新以更好地解释不同搜索策略的原因] 项目高度倾斜。使用数据,我发现大约一半的搜索将在 10,000 行之前完成,40% 可能需要几百万行才能找到足够的匹配项,而 10% 不会在整个文本文件中找到足够的匹配项。每行中的项目与它们所在的行无关,但行的范围相似(即 100,000-500,000 行相关,1,500,000-1,750,000 行相关等)。对于给定的搜索列表,代码可以运行多次,并且对于每次运行,优先级可能是关注不同范围的行。如果整个文本文件只有x行与特定搜索列表中的项目,那么结果将始终是那些x行。但是对于许多搜索列表,有2x、10x或100,000x行匹配,并且在不同的时间,我想选择不同的行。在某些时候,一个特定的范围可能是优先级,在其他时候随机采样是最好的,有时只从头开始找到前x行就可以了,因此“正常”、“随机”和“桶”搜索策略。
我真的很感激任何关于“随机”和“桶”的想法,因为我不确定如何最好地有效地接近它们。我玩弄linecache
, itertools islice
, readlines
(根据@Martin Thoma 在这个答案中,readlines
速度非常快),以及修改上面的代码,但我对“随机”和“桶”的尝试都是笨拙、低效的,我知道我不知道什么是最好的:)。
有什么建议么?谢谢。