简体   繁体   English

从 2D 阵列滑动窗口,沿轴 = 0 或行滑动以提供 3D 阵列

[英]Sliding windows from 2D array that slides along axis=0 or rows to give a 3D array

I have a 2-d numpy array of this form:我有一个这种形式的二维 numpy 数组:

[[  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.]
 [ 40.  41.  42.  43.  44.]
 [ 45.  46.  47.  48.  49.]]

I want to construct a view of the array, grouping its elements in a moving window (of size 4 in my example).我想构建一个数组视图,将其元素分组在一个移动窗口中(在我的示例中为 4 大小)。 My result should be of shape (6, 4, 5) and I can construct it as follows:我的结果应该是形状(6, 4, 5) ,我可以按如下方式构造它:

res = []
mem = 4
for i in range(mem, X.shape[0]+1):
    res.append(X[i-mem:i, : ])
res = np.asarray(res)
print res.shape

I want to avoid reallocation, so I wonder if I can construct a view to give this result, with as_strided for example.我想避免重新分配,所以我想知道我是否可以构建一个视图来给出这个结果,例如 as_strided。

An explanation of the process is very welcome.非常欢迎对该过程的解释。

Thanks谢谢

Here's an approach with requested np.lib.stride_tricks.as_strided -这是一种请求np.lib.stride_tricks.as_strided的方法 -

def strided_axis0(a, L): 
    # INPUTS :
    # a is array
    # L is length of array along axis=0 to be cut for forming each subarray

    # Length of 3D output array along its axis=0
    nd0 = a.shape[0] - L + 1

    # Store shape and strides info
    m,n = a.shape
    s0,s1 = a.strides

    # Finally use strides to get the 3D array view
    return np.lib.stride_tricks.as_strided(a, shape=(nd0,L,n), strides=(s0,s0,s1))

Sample run -样品运行 -

In [48]: X = np.arange(35).reshape(-1,5)

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]])

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

       [[ 5,  6,  7,  8,  9],
        [10, 11, 12, 13, 14],
        [15, 16, 17, 18, 19],
        [20, 21, 22, 23, 24]],

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

       [[15, 16, 17, 18, 19],
        [20, 21, 22, 23, 24],
        [25, 26, 27, 28, 29],
        [30, 31, 32, 33, 34]]])

I wrote this function:我写了这个函数:

    import numpy as np
    
    def indices_moving_window(arr, win):
        win_h = win[0]
        win_w = win[1]
    
        fh = arr.shape[0] - win_h + 1  # Final height
        fw = arr.shape[1] - win_w + 1  # Final width
    
        # Generate indices needed to iterate through the array with the moving window
        ir = np.repeat(np.arange(fh), win_w).reshape(1, -1, win_w)
        ir = np.repeat(ir, win_h, axis=1).reshape(-1, win_h, win_w)
        ir = np.add(ir, np.arange(win_h).reshape(-1, win_h, 1))
        ir = np.repeat(ir, fw, axis=0).reshape(fh, fw, win_h, win_w)
    
        ic = np.repeat(np.arange(fw), win_h).reshape(1, -1, win_h)
        ic = np.repeat(ic, win_w, axis=1).reshape(-1, win_h, win_w)
        ic = np.add(ic, np.arange(win_w))
        ic = ic.reshape(-1, win_w)
        ic = np.tile(ic, (fh, 1))
        ic = ic.reshape(fh, fw, win_h, win_w)
    
        return ir, ic  # Return indices for rows and columns

Example:例子:

arr = np.arange(1,21).reshape(4,5)
rows, cols = indices_moving_window(arr, (3,4))
print(arr)
print(arr[rows,cols])

Output:输出:

[[ 1  2  3  4  5]
 [ 6  7  8  9 10]
 [11 12 13 14 15]
 [16 17 18 19 20]]


[[[[ 1  2  3  4]
   [ 6  7  8  9]
   [11 12 13 14]]

  [[ 2  3  4  5]
   [ 7  8  9 10]
   [12 13 14 15]]]


 [[[ 6  7  8  9]
   [11 12 13 14]
   [16 17 18 19]]

  [[ 7  8  9 10]
   [12 13 14 15]
   [17 18 19 20]]]]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM