获取Numpy 2D数组中每个子矩阵的最大元素索引
问题描述:
我有一个2D Numpy ndarray,x
,需要将其拆分为大小为s
的方形子区域。对于每个次区域,我想获得最大的因素(我所做的),以及它在该次区域的立场(我想不出)。获取Numpy 2D数组中每个子矩阵的最大元素索引
这里是一个小例子:
>>> 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]])
例如,在mx
左下角的8
是从子区域[[1,6], [8, 7]]
在x
左下角的最大元素。
我想要的是得到类似mx
阵列,即保持指数的最大元素的,像这样:
[[0, 1, 1, 2],
[0, 2, 3, 2],
[2, 2, 2, 2]]
其中,例如,在左下角的2
是线性表示为[[1, 6], [8, 7]]
的8
的索引。
我可以这样做:np.argmax(f[i, :, j, :])
并遍历i
和j
,但速度差异对于大量的计算是巨大的。为了给你一个想法,我试图使用(只)Numpy的max pooling。基本上,我问是否有比我使用的更快的替代方案。
答
这里有一个方法 -
# 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]])