使pool.map中的函数作用于其多个参数的一个特定参数

时间:2015-07-10 13:05:30

标签: python arrays multiprocessing

在以下代码中,我想对sum_中包含的z的三个不同值进行多处理np.array([1,2,3])

from multiprocessing import Pool
from functools import partial
import numpy as np

def sum_(x, y, z):
    return x**1+y**2+z**3

sum_partial = partial(sum_, x = 1, y = 2)  # freeze x and y
a = np.array([1,2,3])  # three different values for z

p = Pool(4)
p.map(sum_partial, a)

p.map(sum_partial, a)出现以下错误:TypeError: sum_() got multiple values for keyword argument 'x',因为对于Python,我将a重新分配给我的函数的kwarg x。如何使np.array([1,2,3])的每个变量填充z而不是sum_的参数x,以便我可以获得以下结果:

[6, 13, 32]

分别是:

sum_partial(z=1), sum_partial(z=2), sum_partial(z=3)

? 我想继续使用pool.map

顺便说一句,可以使用多个处理同时使用y数组和z数组来最终得到len(y)*len(z)值的列表吗?

2 个答案:

答案 0 :(得分:0)

我找到了答案here

就我而言,它将是:

import multiprocessing as mp

def sum_(x, y, z):
    return x**1+y**2+z**3

def mf_wrap(args):
    return sum_(*args)

p = mp.Pool(4)

a = [1,2,3]
b = [0.1,0.2,0.3]
fl = [(1, i, j) for i in a for j in b]
#mf_wrap = lambda args: myfun(*args) -> this sucker, though more pythonic and compact, won't work

p.map(mf_wrap, fl)

答案 1 :(得分:0)

根据this threadPEP309,您似乎无法用partial替换函数的第一个最左边的参数。 因此,您应该稍微修改您的代码,以便您的可迭代z是第一个参数:

def sum_(z, x, y):
    return x**1+y**2+z**3

这对我有用并产生预期效果。

修改: 关于第二个问题,您可以使用itertools生成参数:

import itertools
a = [1, 2, 3]
b = [7, 8, 9]
c = list(itertools.product(a, b))
print c

Out[74]: [(1, 7), (1, 8), (1, 9), (2, 7), (2, 8), (2, 9), (3, 7), (3, 8), (3, 9)]

在这种情况下,您的sum_应该期望一个元组作为输入:

def sum_(values, z):
    x, y = values
    return x**1+y**2+z**3

sum_partial = partial(sum_, z=2)
map(sum_partial, c)

Out[88]: [58, 73, 90, 59, 74, 91, 60, 75, 92]