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

Posted

技术标签:

【中文标题】使用邻域和对 3D 数组进行二次采样【英文标题】:Subsampling 3D array using the neighbourhood sum 【发布时间】:2019-10-22 06:56:21 【问题描述】:

标题可能令人困惑。我有一个相当大的 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】:

有一个内置函数可以执行这些逐块缩减 - 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]]])

使用其他缩减 ufunc,比如 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)

【讨论】:

以上是关于使用邻域和对 3D 数组进行二次采样的主要内容,如果未能解决你的问题,请参考以下文章

对numpy数组中的每个第n个条目进行二次采样

如何根据数组的密度对数组进行二次采样? (去除频繁值,保留稀有值)

禁用 Java ImageIO 色度二次采样

如何对二维多边形进行二次采样?

变长df二次采样函数r

对稀疏 scipy 矩阵进行切片以对每 10 行和每列进行二次采样