【问题标题】:python for-loop parallelization using multiprocessing.poolpython for循环并行化使用multiprocessing.pool
【发布时间】:2015-06-18 20:13:55
【问题描述】:

我有一段代码如下所示:

def calc_stuff(x,a,b,c):
    ...
    return y
x = range(N)
y = zeros(x.shape)
if __name__ == '__main__':
    p = Pool(nprocs)
    y = p.map(calc_stuff,x,a,b,c)

这不起作用,正如我在网上搜索的那样,这是因为 map 函数处理的是可迭代对象而不是参数列表。我想知道修改此代码以使其并行化的最简单方法是什么,即 x 是我要并行化的数组/可迭代对象。

谢谢。

【问题讨论】:

    标签: python-2.7 multiprocessing


    【解决方案1】:

    一种选择是使用itertools.repeatzip(或itertools.izip)将多个参数构建成一个可迭代的元组,然后使用multiprocessing.Pool.starmap 调用函数,并将解包的元组作为参数:

    from itertools import repeat
    
    if __name__ == '__main__':
        p = Pool(nprocs)
        y = p.starmap(calc_stuff, zip(x, repeat(a), repeat(b), repeat(c)))
    

    【讨论】:

    • starmap不是itertools吗? p.starmap 给我错误:'Pool' Objects has no attribute 'starmap'
    • 哦,显然starmap 已添加到 Python 3.3 中的 Pool 类中,因此它在 2.7 中不适用于您。也许您可以修改您的工作函数以获取一个元组并将其解压缩到各个变量中? def calc_stuff(tup): x, a, b, c=tup...
    【解决方案2】:

    查看functools.partial,它可以将带有您不想迭代的那些必需参数的函数转换为新函数。

    from multiprocessing import Pool
    import functools
    
    def calc_stuff(a,b,c, x):
        return x+a+b+c
    
    N = 10
    x = list(range(N))
    a = 1
    b = 2
    c = 3
    if __name__ == '__main__':
        nprocs = 4
        p = Pool(nprocs)
        calc_stuff_p = functools.partial(calc_stuff, a, b, c)
        y = p.map(calc_stuff_p, x)
    print(y)
    

    结果

    [6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
    

    请注意,您的可迭代 x 现在位于 calc_stuff 的最后,因为 partial 返回的函数会将任何参数附加到现有参数列表中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-03-17
      • 2019-08-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多