8

Say I have an array like so:

array([1, 2, 3, 4, 5, 5, 7, 8, 9, 10])

I want to change it to

array([1, 2, 3, 4]), array([3, 4, 5, 6]), array([5, 6, 7, 8]), array([7, 8, 9, 10])

Here the window size would be 4, and step size would be 2.

How can I do this in a Python function?

  • 1
    Looks like basic numpy-usage. What did you try? You obviously need to create new arrays, so did you try a list-comprehension, where the start-index is controlley by python's range() with step? – sascha Aug 17 '17 at 08:53
  • Do you want four separate arrays rather than a single 4x4 array? The latter could be more more convenient and is just an application of [`as_strided`](https://docs.scipy.org/doc/numpy/reference/generated/numpy.lib.stride_tricks.as_strided.html). – Alex Riley Aug 17 '17 at 09:00
  • I want the latter –  Aug 17 '17 at 09:00
  • For some more general example of as_strided for this use-case: [skimage's view_as_windows](https://github.com/scikit-image/scikit-image/blob/master/skimage/util/shape.py#L107). – sascha Aug 17 '17 at 09:04

1 Answers1

15

You want numpy.lib.stride_tricks.as_strided

def window(a, w = 4, o = 2, copy = False):
    sh = (a.size - w + 1, w)
    st = a.strides * 2
    view = np.lib.stride_tricks.as_strided(a, strides = st, shape = sh)[0::o]
    if copy:
        return view.copy()
    else:
        return view

Out[]: 
array([[ 1,  2,  3,  4],
       [ 3,  4,  5,  6],
       [ 5,  6,  7,  8],
       [ 7,  8,  9, 10]])

Be sure to set copy = True it if you want to write to the windowed array, as otherwise it is a memory-sharing view.

Daniel F
  • 13,620
  • 2
  • 29
  • 55