多处理具有多个输入的函数

Posted

技术标签:

【中文标题】多处理具有多个输入的函数【英文标题】:Multiprocessing a function with several inputs 【发布时间】:2011-05-26 16:25:10 【问题描述】:

在 Python 中,multiprocessing 模块可用于在一系列值上并行运行函数。例如,这会生成 f 的前 100000 次评估的列表。

def f(i):
    return i * i

def main():
    import multiprocessing
    pool = multiprocessing.Pool(2)
    ans = pool.map(f, range(100000))

    return ans

当 f 接受多个输入但只有一个变量变化时,是否可以做类似的事情?例如,您将如何并行化:

def f(i, n):
    return i * i + 2*n

def main():
    ans = []
    for i in range(100000):
        ans.append(f(i, 20))

    return ans

【问题讨论】:

【参考方案1】:

你可以使用穷人的柯里化(又名 wrap it):

new_f = lambda x: f(x, 20)

然后拨打new_f(i)

【讨论】:

Thils 将与多处理的地图一起工作,因为它不支持不可“导入”的函数(使用 pickle 工具)【参考方案2】:

有几种方法可以做到这一点。在问题中给出的示例中,您可以只定义一个包装函数

def g(i):
    return f(i, 20)

并将这个包装器传递给map()。更通用的方法是有一个包装器,它接受单个元组参数并将元组解包为多个参数

def g(tup):
    return f(*tup)

或使用等效的 lambda 表达式:lambda tup: f(*tup)

【讨论】:

【参考方案3】:

您可以使用functools.partial()

def f(i, n):
    return i * i + 2*n

def main():
    import multiprocessing
    pool = multiprocessing.Pool(2)
    ans = pool.map(functools.partial(f, n=20), range(100000))

    return ans

【讨论】:

我知道这是允许的,但是为什么只有在模块顶层定义的函数可以被腌制? 你能澄清一下关于使用部分的时刻吗 - 看起来它忽略了参数的键:如果我想 pool.map 在第二个参数上 - partial(f, i=20) - 我收到错误:参数有多个值 @987654326 @. @Mikhail_Sam docs.python.org/2/library/functools.html#functools.partial 您要添加到部分的函数需要将第一个参数作为位置参数(例如运行 for 循环时的 'i'),其余的关键字参数应该在之后. 'i' 的所有值都作为列表/范围添加为 'pool.map' 函数的第二个参数。在您的示例中,当“i”的值已经可用作“池”函数的第二个参数时,您在部分函数中提供了一个值“i”,导致您出现自我解释错误/【参考方案4】:

如果您使用我的 multiprocessing 分支,称为 pathos,您可以获得带有多个参数的池......并且还带有 lambda 函数。它的好处是您不必更改编程结构以适应并行工作。

>>> def f(i, n):
...   return i * i + 2*n
... 
>>> from itertools import repeat
>>> N = 10000
>>>
>>> from pathos.pools import ProcessPool as Pool
>>> pool = Pool()
>>>
>>> ans = pool.map(f, xrange(1000), repeat(20))
>>> ans[:10]
[40, 41, 44, 49, 56, 65, 76, 89, 104, 121]
>>>
>>> # this also works
>>> ans = pool.map(lambda x: f(x, 20), xrange(1000))
>>> ans[:10]
[40, 41, 44, 49, 56, 65, 76, 89, 104, 121]

【讨论】:

刚刚安装了 pathos - 能够更好地使用带有闭包等的本地函数,而无需任何全局部分或包装函数或其他任何东西。谢谢你。 @AlexL:请注意,如果您想要与multiprocessing 完全相同的接口但具有更好的序列化,您可以交替使用multiprocesspathos 将其安装为依赖项)。【参考方案5】:

这种技术被称为柯里化:https://en.wikipedia.org/wiki/Currying

不使用functools.partial 的另一种方法是在pool.map 中使用经典的map 命令:

def f(args):
   x, fixed = args
   # FUNCTIONALITY HERE

pool = multiprocessing.Pool(multiprocessing.cpu_count() - 1)
pool.map(f, map(lambda x: (x, fixed), arguments))

【讨论】:

以上是关于多处理具有多个输入的函数的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 tensorflow 构建多输入图?

具有多个输入矩阵的块处理

如何使用多处理 python 顺序运行多个函数?

返回具有多个输入参数的函数的值以在同一类中具有多个参数的另一个函数中使用?

使用 Qt/Phonon 的多声道音频输入

具有多个可能输入的类型检查 Python 方法