2017-04-20 138 views
1

我有一个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, :])并遍历ij,但速度差异对于大量的计算是巨大的。为了给你一个想法,我试图使用(只)Numpy的max pooling。基本上,我问是否有比我使用的更快的替代方案。

回答

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]]) 
相关问题