从2D阵列滑动窗口沿轴= 0滑动,以提供具有动态重叠的3D阵列

时间:2018-10-11 23:43:32

标签: python python-3.x numpy

使用此question的答案,我能够沿着步长= 1的行获得矩阵的窗口化版本(除了一行,每个窗口都是相同的):

def strided_axis0(a, L): 
   nd0 = a.shape[0] - L + 1
   m,n = a.shape
   s0,s1 = a.strides
   return np.lib.stride_tricks.as_strided(a, shape=(nd0,L,n), strides=(s0,s0,s1))

我想在函数中有一个参数以获取不同的重叠。

例如:

In [49]: X
Out[49]: 
array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14],
       [15, 16, 17, 18, 19],
       [20, 21, 22, 23, 24],
       [25, 26, 27, 28, 29],
       [30, 31, 32, 33, 34],
       [35, 36, 37, 38, 39]])

In [50]: strided_axis0(X, L=4, ov = 2)

Out[50]: 
array([[[ 0,  1,  2,  3,  4],
        [ 5,  6,  7,  8,  9],
        [10, 11, 12, 13, 14],
        [15, 16, 17, 18, 19]],

       [[10, 11, 12, 13, 14],
        [15, 16, 17, 18, 19],
        [20, 21, 22, 23, 24],
        [25, 26, 27, 28, 29]],


       [[20, 21, 22, 23, 24],
        [25, 26, 27, 28, 29],
        [30, 31, 32, 33, 34],
        [35, 36, 37, 38, 39]]])

2 个答案:

答案 0 :(得分:1)

您可以尝试:

def get_strides(a, L, ov):
    out = []
    for i in range(0, a.shape[0]-L+1, L-ov):
        out.append(a[i:i+L, :])

    return np.array(out)

基本上,它将生成从第0行开始并向下移动L-ov行的所有数组。当距数组末尾L行时,它将停止。将您的数组作为输入,它将产生:

> print(get_strides(a, 4, 2))
> [[[ 0  1  2  3  4]
    [ 5  6  7  8  9]
    [10 11 12 13 14]
    [15 16 17 18 19]]

  [[10 11 12 13 14]
    [15 16 17 18 19]
    [20 21 22 23 24]
    [25 26 27 28 29]]

  [[20 21 22 23 24]
    [25 26 27 28 29]
    [30 31 32 33 34]
    [35 36 37 38 39]]]

答案 1 :(得分:1)

以下是带有np.lib.stride_tricks.as_strided的版本-

import warnings

def strided_axis0(a, L, overlap=1):
    if L==overlap:
        raise Exception("Overlap arg must be smaller than length of windows")
    S = L - overlap
    nd0 = ((len(a)-L)//S)+1
    if nd0*S-S!=len(a)-L:
        warnings.warn("Not all elements were covered")
    m,n = a.shape
    s0,s1 = a.strides
    return np.lib.stride_tricks.as_strided(a, shape=(nd0,L,n), strides=(S*s0,s0,s1))

我们还可以利用基于np.lib.stride_tricks.as_stridedscikit-image's view_as_windows来获取滑动窗口。 More info on use of as_strided based view_as_windows

from skimage.util.shape import view_as_windows

def strided_axis0(a, L, overlap=1):
    if L==overlap:
        raise Exception("Overlap arg must be smaller than length of windows")
    S = L - overlap
    nd0 = ((len(a)-L)//S)+1
    if nd0*S-S!=len(a)-L:
        warnings.warn("Not all elements were covered")
    return view_as_windows(a, (L,a.shape[1]), step=S)[:,0,:,:]