# Efficient NumPy sliding window function

Here is a function for creating sliding windows from a 1D NumPy array:

from math import ceil, floor
import numpy as np

def slide_window(A, win_size, stride, padding = None):
'''Collects windows that slides over a one-dimensional array.

If padding is None, the last (rightmost) window is dropped if it
'''
if win_size <= 0:
raise ValueError('Window size must be positive.')
if not (0 < stride <= win_size):
raise ValueError(f'Stride must satisfy 0 < stride <= {win_size}.')
if not A.base is None:
raise ValueError('Views cannot be slided over!')

n_elems = len(A)
n_windows = ceil(n_elems / stride)
A = np.pad(A, (0, n_windows * win_size - n_elems),
else:
n_windows = floor(n_elems / stride)
shape = n_windows, win_size

elem_size = A.strides[-1]
return np.lib.stride_tricks.as_strided(
A, shape = shape,
strides = (elem_size * stride, elem_size),
writeable = False)


(Code has been updated based on Marc's feedback) Meant to be used like this:

>>> slide_window(np.arange(5), 3, 2, -1)
array([[ 0,  1,  2],
[ 2,  3,  4],
[ 4, -1, -1]])


Is my implementation correct? Can the code be made more readable? In NumPy 1.20 there is a function called sliding_window_view, but my code needs to work with older NumPy versions.

• numpy.lib.stride_tricks.sliding_window_view is written in pure python; if it is not for the sake of a programming exercise, is there any reason why you can't ... faithfully borrow ... their code? – FirefoxMetzger Mar 18 at 21:06
• It doesn't support padding the last element. Maybe that can be added but it looks like lots of work. – Björn Lindqvist Mar 18 at 21:18

Few suggestions:

• Input validation: there is no input validation for win_size and padding. If win_size is -3 the exception says ValueError: Stride must satisfy 0 < stride <= -3.. If padding is a string, numpy throws an exception.

• f-Strings: depending on the version of Python you use, the exception message can be slightly simplified.

From:

if not (0 < stride <= win_size):
fmt = 'Stride must satisfy 0 < stride <= %d.'
raise ValueError(fmt % win_size)


To:

if not 0 < stride <= win_size:
raise ValueError(f'Stride must satisfy 0 < stride <= {win_size}.')

• Duplication: the statement shape = n_windows, win_size seems duplicated and can be simplified. From:

if padding is not None:
n_windows = ceil(n_elems / stride)
shape = n_windows, win_size
A = np.pad(A, (0, n_windows * win_size - n_elems),
else:
n_windows = floor(n_elems / stride)
shape = n_windows, win_size


To:

if padding is not None:
n_windows = ceil(n_elems / stride)
A = np.pad(A, (0, n_windows * win_size - n_elems),

• Warning: FYI on the doc of np.lib.stride_tricks.as_strided there is a warning that says This function has to be used with extreme care, see notes.. Not sure if it applies to your use case but consider checking it out.