我正在尝试通过较大的3D阵列计算带有滑动窗口的3D补丁的熵。我似乎找不到一种方法来优化代码以任何合理的速度运行。
我目前的工作方法是使用嵌套的for循环,以较大数组的每个坐标为坐标,并以该坐标为起点计算补丁的熵。
我真的很希望能够并行运行此操作,但是似乎无法使 pool.apply()
工作,是否可以并行运行此操作?
这是我的工作代码:
def get_entropy_of_block(data):
value,counts = np.unique(data, return_counts=True)
entropy_of_block = entropy(value, counts)
if np.isnan(entropy_of_block):
entropy_of_block = 0
return entropy_of_block
def output_entropy_versions(mask, window = 5):
mask = np.pad(mask, (0,window - 2), 'edge')
blocks = view_as_windows(mask, (window,window,window),step=1)
entropy_mask = np.zeros(shape=(blocks.shape[0], blocks.shape[1], blocks.shape[2]))
for x in range(blocks.shape[0]):
print(x)
for y in range(blocks.shape[1]):
for z in range(blocks.shape[2]):
entropy_mask[x,y,z] = get_entropy_of_block(blocks[x,y,z,:,:])
return entropy_mask
这是并行尝试
def output_entropy_versions_parallel(mask, window = 5):
mask = np.pad(mask, (0,window - 2), 'edge')
blocks = view_as_windows(mask, (window,window,window),step=1)
entropy_mask = np.zeros(shape=(blocks.shape[0], blocks.shape[1], blocks.shape[2]))
for x in range(blocks.shape[0]):
print(x)
for y in range(blocks.shape[1]):
res = [pool.apply(get_entropy_of_block, args = (blocks[x,y,z,:,:])) for z in range(blocks.shape[2])]
entropy_mask[x,y,:] = res
return entropy_mask
运行此命令,我得到以下信息:
<ipython-input-10-8c3d4ca9d313> in output_entropy_versions(mask, window)
24 print(x)
25 for y in range(blocks.shape[1]):
---> 26 res = [pool.apply(get_entropy_of_block, args = (blocks[x,y,z,:,:])) for z in range(blocks.shape[2])]
27 entropy_mask[x,y,:] = res
28 return entropy_mask
> <ipython-input-10-8c3d4ca9d313> in get_entropy_of_block(data)
10 def get_entropy_of_block(data):
11 value,counts = np.unique(data, return_counts=True)
---> 12 entropy_of_block = entropy(value, counts)
13 if np.isnan(entropy_of_block):
14 entropy_of_block = 0
E:\Anaconda\lib\site-packages\scipy\stats\_distn_infrastructure.py in entropy(pk, qk, base)
2505 """
2506 pk = asarray(pk)
-> 2507 pk = 1.0*pk / np.sum(pk, axis=0)
2508 if qk is None:
2509 vec = entr(pk)
TypeError: unsupported operand type(s) for *: 'float' and 'generator'