如何使用多处理技术将函数应用于二维numpy数组

2024-10-01 13:41:08 发布

您现在位置:Python中文网/ 问答频道 /正文

假设我有以下函数:

def f(x,y):
    return x*y

如何使用多处理模块将函数应用到nxm2dnumpy数组中的每个元素?使用串行迭代,代码可能如下所示:

^{pr2}$

Tags: 模块函数代码元素returndef数组pr2
2条回答

下面是如何使用multiprocesssing并行化示例函数。我还包括了一个几乎完全相同的纯Python函数,它使用非并行for循环,以及一个实现相同结果的numpy one liner:

import numpy as np
from multiprocessing import Pool


def f(x,y):
    return x * y

# this helper function is needed because map() can only be used for functions
# that take a single argument (see http://stackoverflow.com/q/5442910/1461210)
def splat_f(args):
    return f(*args)

# a pool of 8 worker processes
pool = Pool(8)

def parallel(M, N):
    results = pool.map(splat_f, ((i, j) for i in range(M) for j in range(N)))
    return np.array(results).reshape(M, N)

def nonparallel(M, N):
    out = np.zeros((M, N), np.int)
    for i in range(M):
        for j in range(N):
            out[i, j] = f(i, j)
    return out

def broadcast(M, N):
    return np.prod(np.ogrid[:M, :N])

现在我们来看看表演:

^{pr2}$

非并行的纯Python版本比并行化版本高出大约4倍,使用numpy数组广播的版本绝对地压倒了另外两个版本。在

问题是,启动和停止Python子进程会带来大量开销,而且您的测试函数非常小,以至于每个工作线程在其生命周期中只花费很小的一部分时间来做有用的工作。只有当每个线程在被终止之前有大量的工作要做时,多处理才有意义。例如,您可能会给每个worker一个更大的输出数组块来进行计算(尝试将chunksize=参数改为pool.map()),但是对于这样一个小例子,我怀疑您是否会看到很大的改进。在

我不知道你的实际代码是什么样子的-也许你的函数太大了,而且很贵,足以保证使用多处理。然而,我敢打赌,有很多更好的方法来改进它的性能。在

不确定您的案例是否需要多处理。在上面的简单示例中,您可以

X, Y = numpy.meshgrid(numpy.arange(10), numpy.arange(12))
result = X*Y

相关问题 更多 >