在优化移动窗口熵计算方面需要帮助

时间:2019-07-11 15:19:38

标签: python parallel-processing numpy-ndarray entropy parallelism-amdahl

我正在尝试通过较大的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'

0 个答案:

没有答案