我正在尝试学习一种使用numpy来有效解决各种情况下涉及滑动窗口的问题的方法。下面是一个示例,说明了我感兴趣的问题类型:
我有一个很大的二维矩阵,我想对矩阵中每个元素的邻域进行计算。例如,我可能想找出最大值,不包括每个索引处(x-1,y)(x+1,y+1)处的negibor的一些特殊值,然后将结果放入另一个不同的二维“解”矩阵中。
请注意,虽然convolution2d很有用,但在这种情况下对我不起作用,因为我在每个像素上都有特定的操作要做,并且只想在(每个像素的)特定邻居上执行。
还有一个额外的好处就是确保我不会越界。
最后,是否也可以使用任何状态?在所有邻居都为0的情况下,我希望分配一个新的整数id,每次发生这种情况时,我都会递增。
下面是一个示例:
Window:
0 0 1
1 0 0
0 0 0
Input:
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 9 9 0 0 9 0 0
0 0 0 0 0 0 0 0 0
Output:
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 1 1 0 0 2 0 0
0 0 0 0 0 0 0 0 0发布于 2015-09-19 05:11:42
使用np.roll()创建辅助矩阵。然后在初始矩阵和次要矩阵之间执行所需的任何操作。例如,取中心小区和两个邻居的平均值:
sec_a = np.roll(mtrx, -1, axis=0)
sec_b = np.roll(mtrx, -1, axis=1)
result = (mtrx + sec_a + sec_b) / 3此外,roll()在边缘滚动,因此无需担心边界。
发布于 2015-09-19 05:23:30
我曾经创建了这个函数来将2D数组中的滑动块存储到列中,这样我们曾经认为在2D数组上的滑动窗口中应用的任何操作都可以很容易地应用到列中。在this solution to Implement Matlab's im2col 'sliding' in python中了解更多信息。
现在,NumPy支持沿指定的轴应用它的大多数函数。因此,有了这个工具,我们可以有效地以vectorized的方式在滑动窗口中应用几乎任何操作。这是它的正式定义-
def im2col(A,BLKSZ):
# Parameters
M,N = A.shape
col_extent = N - BLKSZ[1] + 1
row_extent = M - BLKSZ[0] + 1
# Get Starting block indices
start_idx = np.arange(BLKSZ[0])[:,None]*N + np.arange(BLKSZ[1])
# Get offsetted indices across the height and width of input array
offset_idx = np.arange(row_extent)[:,None]*N + np.arange(col_extent)
# Get all actual indices & index into input array for final output
return np.take (A,start_idx.ravel()[:,None] + offset_idx.ravel())下面是我们如何使用这个工具来解决手头的问题,假设A是2D输入数组-
# Get 3x3 sliding blocks from A and set them as columns.
Acol = im2col(A,[3,3])
# Setup kernel mask
kernel = np.ones((3,3),dtype=bool)
kernel[2,1:] = 0
# Mask rows of Acol with kernel and perform any operation, let's say MAX
out = Acol[kernel.ravel()].max(0).reshape(A.shape[0]-2,A.shape[1]-2)示例运行-
In [365]: A
Out[365]:
array([[83, 84, 46, 9, 25],
[32, 8, 31, 45, 58],
[14, 8, 0, 51, 27],
[31, 40, 7, 27, 71]])
In [366]: kernel = np.ones((3,3),dtype=bool)
...: kernel[2,1:] = 0
...:
In [367]: im2col(A,[3,3])[kernel.ravel()].max(0).reshape(A.shape[0]-2,A.shape[1]-2)
Out[367]:
array([[84, 84, 58],
[32, 51, 58]])发布于 2015-09-19 06:20:15
假设您的原始2D矩阵名为A,大小为(n,m)
# extraction of 3x3 sub-matrices and storage in a new 2D matrix
B = [ [ A[i-1:i+2, j-1:j+2] for i in range(1, n-1) ] for j in range(1, m-1) ]
# conversion to a mask array
B = np.ma.array( B, mask=False )
# masking the unwanted elements of each sub-matrix
B.mask[:, :, 1, 2] = True
B.mask[:, :, 2, 2] = True注:在创建子矩阵时选择i和j的范围是为了避开边界。
对子矩阵Bi,j的操作将忽略被屏蔽的元素。
现在,要对每个子矩阵执行数值运算(例如子矩阵的最大值),并将结果存储在2D矩阵中:
C = [ [ np.max(B[i,j]) for i in range(n-2) ] for j in range(m-2) ]https://stackoverflow.com/questions/32660953
复制相似问题