如何在Python中优化搜索大型文件
我有一个包含大约800万行文件名的大文件,我正在尝试搜索包含特定值的文件名。找到一个很好,但问题是我正在尝试搜索大约50k个唯一值,搜索所需的时间非常长如何在Python中优化搜索大型文件,python,file,search,optimization,Python,File,Search,Optimization,我有一个包含大约800万行文件名的大文件,我正在尝试搜索包含特定值的文件名。找到一个很好,但问题是我正在尝试搜索大约50k个唯一值,搜索所需的时间非常长 with open('UniqueValueList.txt') as g: uniqueValues = g.read().splitlines() outF = open("Filenames_With_Unique_Values.txt", "w") with open('Filename
with open('UniqueValueList.txt') as g:
uniqueValues = g.read().splitlines()
outF = open("Filenames_With_Unique_Values.txt", "w")
with open('Filenames_File.txt') as f:
fileLine = f.readlines()
for line in fileLine:
for value in uniqueValues:
if value in line:
outF.write(line)
outF.close()
我无法将文件名文件加载到内存中,因为它太大了。有没有其他方法可以优化此搜索?我们可以将文件对象用作迭代器。迭代器将一行一行地返回可以处理的每一行。这不会将整个文件读入内存,并且适合在Python中读取大型文件 帮助你自己学习这个清晰的教程 我的两个理论是:(1)内存映射文件,并在每次值搜索中使用多行正则表达式;(2)将计算结果分成多个子流程。我将两者结合起来,得出以下结论。在父进程和共享中执行mmap是可能的,但我选择了简单的方法,只是在每个子进程中执行,假设操作系统能够为您找到高效的共享
import multiprocessing as mp
import os
import mmap
import re
def _value_find_worker_init(filename):
"""Called when initializing mp.Pool to open an mmaped file in subprocesses.
The file is `global mmap_file` so that the worker can find it.
"""
global mmap_file
filenames_fd = os.open(filename, os.O_RDONLY)
mmap_file = mmap.mmap(filenames_fd, length=os.stat(filename).st_size,
access=mmap.ACCESS_READ)
def _value_find_worker(value):
"""Return a list of matching lines in `global mmap_file`"""
# multiline regex for findall
regex = b"(?m)^.*?" + value + b".*?$"
matched = re.compile(regex).findall(mmap_file)
print(regex, matched)
return matched
def find_unique():
with open("UniqueValueList.txt", "rb") as g:
uniqueValues = [line.strip() for line in g]
with open('UniqueValueList.txt', "rb") as g:
uniqueValues = [line.strip() for line in g]
with mp.Pool(initializer=_value_find_worker_init,
initargs=("Filenames_File.txt",)) as pool:
matched_values = set()
for matches in pool.imap_unordered(_value_find_worker, uniqueValues):
matched_values.update(matches)
with open("Filenames_With_Unique_Values.txt", "wb") as outfile:
outfile.writelines(value + b"\n" for value in matched_values)
find_unique()
不要试图读取整个文件(这是您使用
fileLine=f.readlines()
所做的)。只需对文件的行进行迭代:以获得f:
中的行。如果仍然太慢,您可能必须改进在每行中查找50k不同值的方式。您是在linux和mac这样的分叉系统上,还是在windows这样的衍生系统上?如果使用forking,一旦构建了文件行,您就可以运行一个多处理池,并对值进行分割以在其中进行搜索。甚至可以为每个进程编写一个临时文件,然后在最后连接它们。我不知道它是否会更快,但有了50k的值,它可能会更快。最重要的是,使用操作系统的文本搜索功能,而不是解释性语言。第一件事是在找到匹配项后跳出内部for循环。@Wups-这可以很好地工作,但取决于OP的意图。如果一个值可以匹配多个文件名,则需要搜索所有行。