我有一个应该由一些嵌套循环填充的多维数组(result)。function fun()是一个复杂且耗时的函数。我想以并行的方式填充数组元素,这样我就可以使用系统的所有处理能力。代码如下:
import numpy as np
def fun(x, y, z):
# time-consuming computation...
# ...
return output
dim1 = 10
dim2 = 20
dim3 = 30
result = np.zeros([dim1, dim2, dim3])
for i in xrange(dim1):
for j in xrange(dim2):
for k in xrange(dim3):
result[i, j, k] = fun(i, j, k)我的问题是“我能不能并行化这段代码?如果能,如何并行化?”
我使用的是Windows 10 64位和python 2.7。
如果可以,请通过更改我的代码来提供您的解决方案。谢谢!
发布于 2016-12-22 03:23:29
如果你想要一个更通用的解决方案,利用完全并行执行的优势,那么为什么不使用下面这样的东西:
>>> import multiprocess as mp
>>> p = mp.Pool()
>>>
>>> # a time consuming function taking x,y,z,...
>>> def fun(*args):
... import time
... time.sleep(.1)
... return sum(*args)
...
>>> dim1, dim2, dim3 = 10, 20, 30
>>> import itertools
>>> input = ((i,j,k) for i,j,k in itertools.combinations_with_replacement(xrange(dim3), 3) if i < dim1 and j < dim2)
>>> results = p.map(fun, input)
>>> p.close()
>>> p.join()
>>>
>>> results[:2]
[0, 1]
>>> results[-2:]
[56, 57]注意,我使用的是multiprocess而不是multiprocessing,但这只是为了获得在解释器中工作的能力。
我没有用numpy.array,但如果你非要用...您可以将p.map的输出直接转储到numpy.array中,然后将shape属性修改为shape = (dim1, dim2, dim3),也可以这样做:
>>> input = ((i,j,k) for i,j,k in itertools.combinations_with_replacement(xrange(dim3), 3) if i < dim1 and j < dim2)
>>> import numpy as np
>>> results = np.empty(dim1*dim2*dim3)
>>> res = p.imap(fun, input)
>>> for i,r in enumerate(res):
... results[i] = r
...
>>> results.shape = (dim1,dim2,dim3)发布于 2016-11-06 23:55:44
这是一个针对不同k索引并行运行fun(i, j, k)的代码版本。这是通过使用https://docs.python.org/2/library/multiprocessing.html在不同进程中运行fun来完成的
import numpy as np
from multiprocessing import Pool
def fun(x, y, z):
# time-consuming computation...
# ...
return output
def fun_wrapper(indices):
fun(*indices)
if __name__ == '__main__':
dim1 = 10
dim2 = 20
dim3 = 30
result = np.zeros([dim1, dim2, dim3])
pool = Pool(processes=8)
for i in xrange(dim1):
for j in xrange(dim2):
result[i, j] = pool.map(fun_wrapper, [(i, j, k) for k in xrange(dim3)])发布于 2016-11-06 23:35:55
一种简单的方法可以是将数组分成多个部分,并创建一些线程来在这些部分中操作。例如,一个从(0,0,0)到(5,10,15)的部分和另一个从(5,10,16)到(10,20,30)的部分。
您可以使用threading模块并执行以下操作
import numpy as np
import threading as t
def fun(x, y, z):
# time-consuming computation...
# ...
return output
dim1 = 10
dim2 = 20
dim3 = 30
result = np.zeros([dim1, dim2, dim3])
#b - beginning index, e - end index
def work(ib,jb,kb,ie,je,ke):
for i in xrange(ib,ie):
for j in xrange(jb,je):
for k in xrange(kb,ke):
result[i, j, k] = fun(i, j, k)
threads = list()
threads.append(t.Thread(target=work, args(0,0,0,dim1/2,dim2/2,dim3/2))
threads.append(t.Thread(target=work, args(dim1/2,dim2/2,dim3/2 +1,dim1, dim2, dim3))
for thread in threads:
thread.start()您可以通过某种算法定义这些部分,并动态确定线程的数量。希望它能对你有所帮助,或者至少给你一些启发。
https://stackoverflow.com/questions/40450661
复制相似问题