获取Numpy 2D阵列中每个子矩阵的最大元素索引

时间:2017-04-20 12:22:04

标签: python numpy

我有一个2D Numpy ndarray,x,我需要拆分大小为s的方形子区域。对于每个次区域,我想得到最大的元素(我这样做),以及它在该次区域内的位置(我无法弄清楚)。

这是一个最小的例子:

>>> x = np.random.randint(0, 10, (6,8))
>>> x
array([[9, 4, 8, 9, 5, 7, 3, 3],
       [3, 1, 8, 0, 7, 7, 5, 1],
       [7, 7, 3, 6, 0, 2, 1, 0],
       [7, 3, 9, 8, 1, 6, 7, 7],
       [1, 6, 0, 7, 5, 1, 2, 0],
       [8, 7, 9, 5, 8, 3, 6, 0]])
>>> h, w = x.shape
>>> s = 2
>>> f = x.reshape(h//s, s, w//s, s)
>>> mx = np.max(f, axis=(1, 3))
>>> mx
array([[9, 9, 7, 5],
       [7, 9, 6, 7],
       [8, 9, 8, 6]])

例如,8左下角的mx是来自[[1,6], [8, 7]]左下角的子区域x的最大元素。

我想要的是获得一个类似于mx的数组,它保留最大元素的 indices ,如下所示:

[[0, 1, 1, 2],
 [0, 2, 3, 2],
 [2, 2, 2, 2]]

例如,左下角的28的线性表示中[[1, 6], [8, 7]]的索引。

我可以这样做:np.argmax(f[i, :, j, :])并迭代ij,但速度差异对于大量计算来说是巨大的。为了给你一个想法,我试图使用(仅)Numpy max pooling。基本上,我问的是否有比我正在使用的更快的替代方案。

1 个答案:

答案 0 :(得分:2)

这是一种方法 -

# Get shape of output array
m,n = np.array(x.shape)//s

# Reshape and permute axes to bring the block as rows
x1 = x.reshape(h//s, s, w//s, s).swapaxes(1,2).reshape(-1,s**2)

# Use argmax along each row and reshape to output shape
out = x1.argmax(1).reshape(m,n)

示例输入,输出 -

In [362]: x
Out[362]: 
array([[9, 4, 8, 9, 5, 7, 3, 3],
       [3, 1, 8, 0, 7, 7, 5, 1],
       [7, 7, 3, 6, 0, 2, 1, 0],
       [7, 3, 9, 8, 1, 6, 7, 7],
       [1, 6, 0, 7, 5, 1, 2, 0],
       [8, 7, 9, 5, 8, 3, 6, 0]])

In [363]: out
Out[363]: 
array([[0, 1, 1, 2],
       [0, 2, 3, 2],
       [2, 2, 2, 2]])

或者,为了简化事情,我们可以使用scikit-image为我们完成重塑和置换轴的繁重工作 -

In [372]: from skimage.util import view_as_blocks as viewB

In [373]: viewB(x, (s,s)).reshape(-1,s**2).argmax(1).reshape(m,n)
Out[373]: 
array([[0, 1, 1, 2],
       [0, 2, 3, 2],
       [2, 2, 2, 2]])