This website works better with desktop in both themes, for mobile devices please change to light theme.

Moving Window Frame

Moving Window Frame#

Lets take this array

length of the array = 10

lets take a moving window = 4

now there are two ways to create a frame.

Iteration By Row#

Iterate by window length and append data in new frame.

like for given example window is 4

index 0 to 3

index 1 to 4

index 2 to 5

index 3 to 6

and so on …

but here the iteration is going to happen for length - window + 1 (10 - 4 + 1 = 7) times. If we have one million rows then this is too big/ long operation.

[1]:
import numpy as np
[2]:
a = np.array([1,2,3,4,5,6,7,8,9,10])

window = 4
start = 0
end = a.shape[0]
frame_length = end - window + 1

print(window, start, end, frame_length)

new_frame = []
for i in range(0,frame_length):
    print(i)
    new_frame.append(a[i:i+window])

np.array(new_frame)
4 0 10 7
0
1
2
3
4
5
6
[2]:
array([[ 1,  2,  3,  4],
       [ 2,  3,  4,  5],
       [ 3,  4,  5,  6],
       [ 4,  5,  6,  7],
       [ 5,  6,  7,  8],
       [ 6,  7,  8,  9],
       [ 7,  8,  9, 10]])

Iteration By Column#

Iterate by Columns first approach and start with length (length - window + 1 ) (10 - 4 + 1 = 7 till 6th index)

transpose it

[3]:
a = np.array([1,2,3,4,5,6,7,8,9,10])

window = 4
start = 0
end = a.shape[0]
frame_width = end - window + 1

print(window, start, end, frame_width)


new_frame = []
for i in range(0, window):
    print(i)
    new_frame.append(a[i:i+frame_width])

np.array(new_frame).T
4 0 10 7
0
1
2
3
[3]:
array([[ 1,  2,  3,  4],
       [ 2,  3,  4,  5],
       [ 3,  4,  5,  6],
       [ 4,  5,  6,  7],
       [ 5,  6,  7,  8],
       [ 6,  7,  8,  9],
       [ 7,  8,  9, 10]])
[4]:
def moving_window_matrix(arr: np.ndarray, window: int, shift: int = 1)-> np.ndarray:

    assert len(np.shape(arr)) == 1, 'input array shape should be 1D like (m,).'
    size = arr.shape[0]

    assert size > window and size > shift, \
        'length of array should be greater than window size and shift.'

    frame_width = size - window + 1

    new_frame = np.zeros(shape=(window, int(np.ceil(frame_width/ shift))))
    for i in range(0, window):
        new_frame[i] = arr[i: i+frame_width][::shift]

    return new_frame.T

%timeit moving_window_matrix(np.arange(1000000), 10, 1)
69.4 ms ± 8.11 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)