Python,添加 key :value to dictionary in parallelised loop

标签 python numpy dictionary joblib

我已经编写了一些代码来并行执行一些计算 (joblib) 并使用计算结果更新字典。该代码由调用生成器函数的主函数和并行运行的计算函数组成。计算结果(键值对)由计算函数的每个实例添加到在主函数和市场中创建的字典中作为全局。

下面是我的代码的简化版本,说明了上述过程。

当一切运行时,结果字典 (d_result) 是空的,但它应该已经填充了计算函数生成的结果。为什么会这样?

import numpy as np
from joblib import Parallel, delayed


def do_calc(d, r, pair_index): # function to be run in parallel

    data_1 = d[str(r)][pair_index, 1]
    data_2 = d[str(r)][pair_index, 2]
    result_name = str(data_1) + " ^ " + str(data_2)
    result = data_1 ** data_2
    d_result[result_name] = result
    # d_result.setdefault(result_name, []).append(result)  ## same result as above


def compute_indices(d): # generator function

    for r in d:
        num_pairs = d[str(r)].shape[0]
        for pair_index in range(num_pairs):
            yield r, pair_index


def process(): # main function

    global d_result
    d_result = {}
    r1 = np.array([['ab', 1, 2], ['vw', 10, 12]], dtype=object)
    r2 = np.array([['ac', 1, 3], ['vx', 10, 13]], dtype=object)
    r3 = np.array([['ad', 1, 4], ['vy', 10, 14]], dtype=object)
    r4 = np.array([['ae', 1, 5], ['vz', 10, 15]], dtype=object)
    d = {'r1': r1, 'r2': r2, 'r3': r3, 'r4': r4}
    Parallel(n_jobs=4)(delayed(do_calc)(d, r, pair_index) for r, pair_index in (compute_indices)(d))
    print(d_result)


process()

最佳答案

很高兴您的程序可以运行。但是我认为您忽略了一些重要的事情,如果您将您的示例用作更大程序的基础,您可能会遇到麻烦。

我扫描了 joblib 的文档,发现它是基于 Python 多处理模块构建的。所以 multiprocessing programming guidelines申请。

一开始我想不通为什么你的新程序运行成功而原来的程序运行失败。原因如下(来自上面的链接):“请记住,如果在子进程中运行的代码试图访问全局变量,那么它看到的值(如果有的话)可能与父进程中的值不同Process.start 被调用时的进程。”这是因为至少在概念上,每个子进程都有自己的 Python 解释器副本。在每个子进程中,必须导入该进程使用的代码。如果该代码声明了全局变量,那么这两个进程将拥有这些全局变量的单独副本,即使您阅读代码时看起来并不是那样。所以当你原来程序的子进程往全局的d_result里放数据的时候,其实和父进程里的d_result是不同的对象。再次来自文档:“确保新的 Python 解释器可以安全地导入主模块,而不会导致意外的副作用(例如启动新进程)。

例如,在 Windows 下运行以下模块将失败并出现 RuntimeError:

from multiprocessing import Process

def foo():
    print 'hello'

p = Process(target=foo)
p.start()

相反,应该使用 if __name__ == '__main__' 来保护程序的入口点。”

因此,在最后一行之前向您的程序(第二个版本)添加一行代码很重要:

if __name__ == "__main__":
    process()

如果不这样做,可能会导致一些您不想花时间处理的讨厌的错误。

关于Python,添加 key :value to dictionary in parallelised loop,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43200878/

相关文章:

python - 使用python映射到整数后如何防止前导零

python - ' | ' python 集合对象之间的运算符

python - 更新字典值中的列表

python - 打印排序的字典键和排序的值

python - 从 float 列表中,如何在 Python 中只保留尾数?

firebase - 怎么把Firebase Map转换成Dart Map?

python - 使用 Python 和 xlwings 在 Excel 中查找事件/选定单元格的范围 - 续

python - 比较Python中的列表和获取索引

python - 如何在flask-sqlalchemy中为API端点设置唯一的字符串主键

python - Curve_fit 到 apply_along_axis。如何加快速度?