[英]How to apply a function to a 2D numpy array with multiprocessing
假设我有以下功能:
def f(x,y):
return x*y
如何使用多处理模块将功能应用于NxM 2D numpy数组中的每个元素? 使用串行迭代,代码可能如下所示:
import numpy as np
N = 10
M = 12
results = np.zeros(shape=(N,M))
for x in range(N):
for y in range(M):
results[x,y] = f(x,y)
以下是使用multiprocesssing
并行化示例函数的方法。 我还包括一个几乎相同的纯Python函数,它使用非并行for
循环,以及一个实现相同结果的numpy单行程:
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])
现在让我们来看看性能:
%timeit parallel(1000, 1000)
# 1 loops, best of 3: 1.67 s per loop
%timeit nonparallel(1000, 1000)
# 1 loops, best of 3: 395 ms per loop
%timeit broadcast(1000, 1000)
# 100 loops, best of 3: 2 ms per loop
非并行纯Python版本比并行化版本大约4倍,而使用numpy数组广播的版本绝对会破坏其他两个版本。
问题是启动和停止Python子进程会带来相当多的开销,并且您的测试函数非常简单,以至于每个工作线程只花费其生命周期的一小部分来完成有用的工作。 如果每个线程在被杀死之前都有大量的工作要做,那么多处理才有意义。 例如,你可以给每个工作者一个更大的输出数组来计算(尝试使用chunksize=
参数到pool.map()
),但是有了这样一个简单的例子,我怀疑你会看到一个很大的改进。
我不知道你的实际代码是什么样的 - 也许你的功能很大而且价格昂贵,足以保证使用多处理。 不过,我敢打赌,有很多更好的方法来提高其性能。
在您的情况下,不确定是否需要多处理。 在上面的简单示例中,您可以这样做
X, Y = numpy.meshgrid(numpy.arange(10), numpy.arange(12))
result = X*Y
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.