Home > Mobile >  Sliding window on a 2D NumPy array with axis=0
Sliding window on a 2D NumPy array with axis=0

Time:11-30

I have a np.array a such that a.shape = (10, 5) and I want to use a sliding window of size 3 so that the output array b.shape = (8, 15).

For example

i, j = np.ogrid[:10, :5]
a = 10*i   j
print(a)
array([[ 0,  1,  2,  3,  4],
       [10, 11, 12, 13, 14],
       [20, 21, 22, 23, 24],
       [30, 31, 32, 33, 34],
       [40, 41, 42, 43, 44],
       [50, 51, 52, 53, 54],
       [60, 61, 62, 63, 64],
       [70, 71, 72, 73, 74],
       [80, 81, 82, 83, 84],
       [90, 91, 92, 93, 94]])

Then b should be

array([[ 0,  1,  2,  3,  4, 10, 11, 12, 13, 14, 20, 21, 22, 23, 24],
       [10, 11, 12, 13, 14, 20, 21, 22, 23, 24, 30, 31, 32, 33, 34],
       [20, 21, 22, 23, 24, 30, 31, 32, 33, 34, 40, 41, 42, 43, 44],
       [30, 31, 32, 33, 34, 40, 41, 42, 43, 44, 50, 51, 52, 53, 54],
       [40, 41, 42, 43, 44, 50, 51, 52, 53, 54, 60, 61, 62, 63, 64],
       [50, 51, 52, 53, 54, 60, 61, 62, 63, 64, 70, 71, 72, 73, 74],
       [60, 61, 62, 63, 64, 70, 71, 72, 73, 74, 80, 81, 82, 83, 84],
       [70, 71, 72, 73, 74, 80, 81, 82, 83, 84, 90, 91, 92, 93, 94]])

I tried numpy.lib.stride_tricks.sliding_window_view but it seems not working for this scenario.

CodePudding user response:

Here you can use one concatenate:

i, j = np.ogrid[:9, :5]
a = 10*i   j #generate your array


b = np.concatenate( [a[:-2,:],a[1:-1,:],a[2:,:]],axis=1)

print(b)
#returns 
array([[ 0,  1,  2,  3,  4, 10, 11, 12, 13, 14, 20, 21, 22, 23, 24],
       [10, 11, 12, 13, 14, 20, 21, 22, 23, 24, 30, 31, 32, 33, 34],
       [20, 21, 22, 23, 24, 30, 31, 32, 33, 34, 40, 41, 42, 43, 44],
       [30, 31, 32, 33, 34, 40, 41, 42, 43, 44, 50, 51, 52, 53, 54],
       [40, 41, 42, 43, 44, 50, 51, 52, 53, 54, 60, 61, 62, 63, 64],
       [50, 51, 52, 53, 54, 60, 61, 62, 63, 64, 70, 71, 72, 73, 74],
       [60, 61, 62, 63, 64, 70, 71, 72, 73, 74, 80, 81, 82, 83, 84]])

Also you can do it for any windows size as

windowSize = 3
nRows,nCols = a.shape
b =np.concatenate([a[c:nRows-(windowSize-c-1),:] for c in range(windowSize)],axis=1)

CodePudding user response:

Using numpy.lib.stride_tricks.sliding_window_view, simply slide on the flattened array and slice the elements you want:

import numpy as np
np.lib.stride_tricks.sliding_window_view(a.ravel(), 15)[::a.shape[1]]

output:

array([[ 0,  1,  2,  3,  4, 10, 11, 12, 13, 14, 20, 21, 22, 23, 24],
       [10, 11, 12, 13, 14, 20, 21, 22, 23, 24, 30, 31, 32, 33, 34],
       [20, 21, 22, 23, 24, 30, 31, 32, 33, 34, 40, 41, 42, 43, 44],
       [30, 31, 32, 33, 34, 40, 41, 42, 43, 44, 50, 51, 52, 53, 54],
       [40, 41, 42, 43, 44, 50, 51, 52, 53, 54, 60, 61, 62, 63, 64],
       [50, 51, 52, 53, 54, 60, 61, 62, 63, 64, 70, 71, 72, 73, 74],
       [60, 61, 62, 63, 64, 70, 71, 72, 73, 74, 80, 81, 82, 83, 84],
       [70, 71, 72, 73, 74, 80, 81, 82, 83, 84, 90, 91, 92, 93, 94]])
  • Related