Re-arranging the array's strides:
import numpy as np
from numpy.lib.stride_tricks import as_strided
def windows(a, window = (2,2), ss = None, flatten = True):
'''
Return a sliding window over a.
a - numpy ndarray
window - shape of the window, int for 1d or tuple for 2d+
ss - int for 1d or tuple for 2d+ how much to slide the window
defaults to window (no overlap)
flatten - if True, all slices are flattened, otherwise, there is an
extra dimension for each dimension of the input.
Returns
an array containing each n-dimensional window from a
'''
if ss is None:
ss = window
data_shape = np.array(a.shape)
# how many windows are there?
windowed_array_shape = tuple(((data_shape - window) // window) + 1)
nbr_windows = np.product(windowed_array_shape)
# the shape of the windowed array
newshape = windowed_array_shape + window
# calculate the strides for the windowed array
newstrides = tuple(np.array(a.strides) * window) + a.strides
# use as_strided to 'transform' the array
windowed_array = as_strided(a, shape = newshape, strides = newstrides)
if not flatten:
return windowed_array
# flatten the windowed array for iteration
dim = (nbr_windows,) + window
windowed_array = windowed_array.reshape(dim)
return windowed_array
a = np.array([[1,1,1,1,2,2,2,2],
[1,1,1,1,2,2,2,2],
[1,1,1,1,2,2,2,2],
[1,1,1,1,2,2,2,2],
[3,3,3,3,4,4,4,4],
[3,3,3,3,4,4,4,4],
[3,3,3,3,4,4,4,4],
[3,3,3,3,4,4,4,4]])
>>> b = windows(a, (4,4))
>>> b
array([[[1, 1, 1, 1],
[1, 1, 1, 1],
[1, 1, 1, 1],
[1, 1, 1, 1]],
[[2, 2, 2, 2],
[2, 2, 2, 2],
[2, 2, 2, 2],
[2, 2, 2, 2]],
[[3, 3, 3, 3],
[3, 3, 3, 3],
[3, 3, 3, 3],
[3, 3, 3, 3]],
[[4, 4, 4, 4],
[4, 4, 4, 4],
[4, 4, 4, 4],
[4, 4, 4, 4]]])
>>>
A couple of other options in this SO q&a