使用邻域和对3D数组进行二次采样

时间:2019-06-06 18:07:53

标签: python arrays numpy binning subsampling

标题可能令人困惑。我有一个相当大的3D numpy数组。我想通过合并大小为(2,2,2)的块将其大小减少2 ^ 3。然后,新3D数组中的每个元素都应包含原始数组中其相应块中的元素总和。

例如,考虑一个4x4x4数组:

input = [[[1, 1, 2, 2],
          [1, 1, 2, 2],
          [3, 3, 4, 4],
          [3, 3, 4, 4]],
         [[1, 1, 2, 2],
          [1, 1, 2, 2],
          [3, 3, 4, 4],
          [3, 3, 4, 4]],
              ...    ]]]

(为了节省空间,我只代表其中的一半)。注意,所有具有相同值的元素构成一个(2x2x2)块。输出应为2x2x2数组,这样每个元素都是一个块的总和:

output = [[[8, 16],
          [24, 32]],
             ... ]]]

所以8是所有1的总和,16是2的总和,依此类推。

1 个答案:

答案 0 :(得分:2)

有一个内置的功能可以逐段减少-skimage.measure.block_reduce-

In [36]: a
Out[36]: 
array([[[1, 1, 2, 2],
        [1, 1, 2, 2],
        [3, 3, 4, 4],
        [3, 3, 4, 4]],

       [[1, 1, 2, 2],
        [1, 1, 2, 2],
        [3, 3, 4, 4],
        [3, 3, 4, 4]]])

In [37]: from skimage.measure import block_reduce

In [39]: block_reduce(a, block_size=(2,2,2), func=np.sum)
Out[39]: 
array([[[ 8, 16],
        [24, 32]]])

使用其他归约功能,例如max-reduction-

In [40]: block_reduce(a, block_size=(2,2,2), func=np.max)
Out[40]: 
array([[[1, 2],
        [3, 4]]])

使用NumPy工具实现这样的功能并不困难,并且可以像这样-

def block_reduce_numpy(a, block_size, func):
    shp = a.shape
    new_shp = np.hstack([(i//j,j) for (i,j) in zip(shp,block_size)])
    select_axes = tuple(np.arange(a.ndim)*2+1)
    return func(a.reshape(new_shp),axis=select_axes)