Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/347.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Python中优化搜索大型文件_Python_File_Search_Optimization - Fatal编程技术网

如何在Python中优化搜索大型文件

如何在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

我有一个包含大约800万行文件名的大文件,我正在尝试搜索包含特定值的文件名。找到一个很好,但问题是我正在尝试搜索大约50k个唯一值,搜索所需的时间非常长

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的意图。如果一个值可以匹配多个文件名,则需要搜索所有行。