python - 与多处理并行填充字典

标签 python multiprocess

昨天我问了一个问题:Reading data in parallel with multiprocess

我得到了很好的答案,我实现了我标记为正确的答案中提到的解决方案。

def read_energies(motif):
    os.chdir("blabla/working_directory")
    complx_ener = pd.DataFrame()
    # complex function to fill that dataframe 
    lig_ener = pd.DataFrame()
    # complex function to fill that dataframe 
    return motif, complx_ener, lig_ener

COMPLEX_ENERGIS = {}
LIGAND_ENERGIES = {}
p = multiprocessing.Pool(processes=CPU)
for x in p.imap_unordered(read_energies, peptide_kd.keys()):
    COMPLEX_ENERGIS[x[0]] = x[1]
    LIGAND_ENERGIES[x[0]] = x[2]

但是,此解决方案花费的时间与我只是迭代 peptide_kd.keys() 并一个接一个地填充 DataFrames 所花的时间相同。为什么呢?有没有办法并行填充所需的字典并实际提高速度?我在 48 核 HPC 上运行它。

最佳答案

在 (1) 启动每个进程,以及 (2) 必须跨多个进程复制 pandas.DataFrame(等等)时,您会产生大量开销。如果您只需要并行填充一个dict,我建议您使用共享内存dict。如果没有 key 会被覆盖,那么这很容易,您不必担心锁。

(请注意,我在下面使用了 multiprocess,它是 multiprocessing 的一个分支——但只有这样我才能从解释器中进行演示,否则,您将拥有从 __main__ 执行以下操作。

>>> from multiprocess import Process, Manager
>>> 
>>> def f(d, x):
...   d[x] = x**2
... 
>>> manager = Manager()
>>> d = manager.dict()
>>> job = [Process(target=f, args=(d, i)) for i in range(5)]
>>> _ = [p.start() for p in job]
>>> _ = [p.join() for p in job]
>>> print d
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16}

此解决方案不会复制 dict 以在进程之间共享,因此减少了部分开销。对于像 pandas.DataFrame 这样的大型对象,与像 x**2 这样的简单操作的成本相比,它可能是非常重要的。类似地,产生一个 Process 可能需要时间,并且您可以通过使用线程(即来自 multiprocess.dummy 而不是multiprocess 用于您最初发布的解决方案或我上面的解决方案)。

如果您确实需要共享DataFrames(正如您的代码所建议的那样而不是问题所要求的那样),您可以通过创建共享内存numpy.ndarray.

关于python - 与多处理并行填充字典,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38393269/

相关文章:

python - 将大文件发送到python中的PIPE输入

python - 清理重新匹配对象

python - 如何使用 PyGame 淡出和返回屏幕?

python - Nose 多进程问题

python - 我似乎找不到一种方法来获取 Pyqtgraph 中 ScatterPlotItem 所有点的列表

python - fusion-python xmp.py - 无法创建文件

python - 为什么多进程 python grpc 服务器不起作用?

multithreading - 动态更新 basic_qos 预取,以防止在确认后工作人员仍然忙碌时预取消息

android - 多进程共享首选项在多进程环境中返回错误值

python - 添加额外的随机参数作为 python 3.4.7 中 pool.map 函数的参数