代码之家  ›  专栏  ›  技术社区  ›  0x90 Salvador Dali

如何更快地获得大量的子矩阵?

  •  2
  • 0x90 Salvador Dali  · 技术社区  · 6 年前

    我有一个很大的矩阵( nxn )为此,我将构建具有尺寸的相交瓷砖(子矩阵) mxm . 将有一个偏移量 step b每个相邻子矩阵之间。下面是一个例子 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]
    

    有没有更快的方法来初始化子矩阵?

    2 回复  |  直到 6 年前
        1
  •  3
  •   Divakar    6 年前

    我们可以利用杠杆 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)
    

    或者,我们可以用列表理解来提取行和列索引,然后用它们来索引,就像这样。-

    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 精氨酸 视窗ASSWindows 像这样——

    view_as_windows(matrix,(m,m),step=2)
    

    这会给我们一个 4D 数组和索引到它的前两个轴将具有 mxm 塑形窗户。这些窗口只是输入视图,因此没有额外的内存开销,加上几乎免费的运行时!

        2
  •  1
  •   milkice    6 年前
    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]