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)