我有一个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]]
例如,左下角的2
是8
的线性表示中[[1, 6], [8, 7]]
的索引。
我可以这样做:np.argmax(f[i, :, j, :])
并迭代i
和j
,但速度差异对于大量计算来说是巨大的。为了给你一个想法,我试图使用(仅)Numpy max pooling。基本上,我问的是否有比我正在使用的更快的替代方案。
答案 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]])