从大文件中分块数据进行多处理?

时间:2012-01-03 18:52:56

标签: python parallel-processing

我正在尝试使用多处理并行化应用程序 一个非常大的csv文件(64MB到500MB),做一些逐行工作,然后输出一个小的固定大小 文件。

目前我做了一个list(file_obj),遗憾的是它完全被加载了 进入记忆(我想)然后我把那个列表分成n个部分,n是 我想要运行的进程数。然后我在分手时做pool.map() 名单。

与单个版本相比,这似乎有一个非常非常糟糕的运行时 线程化,只是打开文件和迭代的方法。有人可以 建议一个更好的解决方案?

此外,我需要以保留的组处理文件的行 某列的值。这些行组本身可以分开, 但是没有任何组应该包含此列的多个值。

2 个答案:

答案 0 :(得分:15)

list(file_obj)很大时,

fileobj可能需要大量内存。我们可以通过使用itertools来根据需要提取行块来减少内存需求。

特别是,我们可以使用

reader = csv.reader(f)
chunks = itertools.groupby(reader, keyfunc)

将文件拆分为可处理的块,

groups = [list(chunk) for key, chunk in itertools.islice(chunks, num_chunks)]
result = pool.map(worker, groups)

让多处理池一次在num_chunks个块上运行。

通过这样做,我们只需要足够的内存来在内存中保存一些(num_chunks)块,而不是整个文件。


import multiprocessing as mp
import itertools
import time
import csv

def worker(chunk):
    # `chunk` will be a list of CSV rows all with the same name column
    # replace this with your real computation
    # print(chunk)
    return len(chunk)  

def keyfunc(row):
    # `row` is one row of the CSV file.
    # replace this with the name column.
    return row[0]

def main():
    pool = mp.Pool()
    largefile = 'test.dat'
    num_chunks = 10
    results = []
    with open(largefile) as f:
        reader = csv.reader(f)
        chunks = itertools.groupby(reader, keyfunc)
        while True:
            # make a list of num_chunks chunks
            groups = [list(chunk) for key, chunk in
                      itertools.islice(chunks, num_chunks)]
            if groups:
                result = pool.map(worker, groups)
                results.extend(result)
            else:
                break
    pool.close()
    pool.join()
    print(results)

if __name__ == '__main__':
    main()

答案 1 :(得分:2)

我会保持简单。有一个程序打开文件并逐行读取。您可以选择将其拆分的文件数,打开多个输出文件,每行写入下一个文件。这会将文件拆分为 n 相等的部分。然后,您可以并行地针对每个文件运行Python程序。