Python:使用多处理每次迭代的 Pickle 输出

Python: Pickle output for each iteration using multiprocessing

我正在尝试并行化我现有的一些代码。我想在每次迭代完成后立即保存它的输出,这样我就不必将整个循环存储在内存中。基本上是这样的:

import cPickle as pickle
from multiprocessing import Pool

if __name__ == '__main__':
    outf = open('test_mp.pkl', 'wb')

    def f(x):
        pickle.dump([x, x*x], outf, -1)
        return x*x

    pool = Pool(4)
    out = pool.map(f, range(100))
    print out

代码运行时没有错误或警告,并为 'out' 生成正确的值。但是,当我尝试读取生成的 pickle 文件时,似乎根本没有写入任何内容:

>>> f = open('test_mp.pkl', 'rb')
>>> pickle.load(f)
---------------------------------------------------------------------------
EOFError                                  Traceback (most recent call last)
<ipython-input-4-4d7131bbd231> in <module>()
----> 1 pickle.load(f)

EOFError:

我目前不知道为什么我不能在循环中间转储到 pickle 对象。我已经在没有多处理的情况下尝试了这段代码(即只是一个 for 循环)并且它工作得很好。

我还将该函数移到了 main() 之外,并将 'outf' 作为附加参数传入。该方法给出了有关尝试写入已关闭文件的错误。

当我的循环被并行化时,如何将我的输出保存在 pickle 文件中?

您将遇到试图同时访问同一个文件句柄的线程的问题。相反,您可以使用 .dumps 方法 pickle 到一个列表中,然后在最后将组合的 bytearray 转储到一个文件中。否则,您可以从每个进程中 pickle 到一个单独的文件句柄中,这样每个进程都会有一个文件。

此外,pickling 并不是存储大量数据的理想方式。有专门设计的文件格式,例如 HDF5 (http://www.h5py.org/),非常适合存储大量数字数据。 h5py 实现非常成熟且易于使用,还可以让您并行存储数据。