我有一个非常大的矩阵(nxn
),为此,我将构建尺寸为mxm
的相交切片(子矩阵)。每个连续子矩阵之间的偏移量为step
。这是n=8, m=4, step=2
的示例:
import numpy as np
matrix=np.random.randn(8,8)
n=matrix.shape[0]
m=4
step=2
这将存储所有拐角索引(x,y)
,我们将从中获取一个4x4的矩阵:(x:x+4,x:x+4)
a={(i,j) for i in range(0,n-m+1,step) for j in range(0,n-m+1,step)}
子矩阵将像这样提取
sub_matrices = np.zeros([m,m,len(a)])
for i,ind in enumerate(a):
x,y=ind
sub_matrices[:,:,i]=matrix[x:x+m, y:y+m]
有没有更快的方法来执行此子矩阵初始化?
答案 0 :(得分:3)
我们可以利用基于np.lib.stride_tricks.as_strided
的scikit-image's view_as_windows
来获取滑动窗口。 More info on use of as_strided
based view_as_windows
。
from skimage.util.shape import view_as_windows
# Get indices as array
ar = np.array(list(a))
# Get all sliding windows
w = view_as_windows(matrix,(m,m))
# Get selective ones by indexing with ar
selected_windows = np.moveaxis(w[ar[:,0],ar[:,1]],0,2)
或者,我们可以使用列表理解来提取row和col索引,然后使用它们进行索引,就像这样-
R = [i[0] for i in a]
C = [i[1] for i in a]
selected_windows = np.moveaxis(w[R,C],0,2)
从一开始就进行优化,我们可以跳过创建步进数组a
,而仅将step
arg与view_as_windows
一起使用,就像这样-
view_as_windows(matrix,(m,m),step=2)
这将给我们一个4D
数组,并在它的前两个轴上建立索引,将具有所有mxm
形的窗口。这些窗口只是输入的视图,因此没有额外的内存开销以及几乎免费的运行时间!
答案 1 :(得分:1)
import numpy as np
a = np.random.randn(n, n)
b = a[0:m*step:step, 0:m*step:step]
如果您具有一维数组,则可以通过以下代码获取它的子矩阵:
c = a[start:end:step]
如果维度为两个或多个,请在每个维度之间添加逗号。
d = a[start1:end1:step1, start2:end3:step2]