5

I want to apply a given function (in particular, the np.std()) to an array of measurements, and I'd like to apply it on a rolling window of a given size.

But - since the measurements are intended to be in a circular array - I also need the rolling window to be able to overlap from the array end to its beginning.

Therefore, I'm unable to use the answer in Rolling window for 1D arrays in Numpy? ... I tried to modify its approach, but I'm not a numpy expert and I was unable to understand what np.lib.stride_tricks.as_strided does (where is its documentation???)

alessandro
  • 3,838
  • 8
  • 40
  • 59

1 Answers1

5

Pad the original array with enough values to make a "pseudo-circular" array. Then apply rolling_window to the pseudo-circular array:

import numpy as np

def rolling_window(a, window):
    # http://www.mail-archive.com/numpy-discussion@scipy.org/msg29450.html
    shape = a.shape[:-1] + (a.shape[-1] - window + 1, window)
    strides = a.strides + (a.strides[-1],)
    return np.lib.stride_tricks.as_strided(a, shape=shape, strides=strides)

def circular_rolling_window(a, window):
    pseudocircular = np.pad(a, pad_width=(0, windowsize-1), mode='wrap')
    return rolling_window(pseudocircular, windowsize)

a = np.arange(5)
windowsize = 3
print(circular_rolling_window(a, windowsize))

yields

[[0 1 2]
 [1 2 3]
 [2 3 4]
 [3 4 0]
 [4 0 1]]
unutbu
  • 842,883
  • 184
  • 1,785
  • 1,677
  • It worked - thanks a lot! To simplify, I just inserted your line a = np.pad(a, pad_width=(0, windowsize-1), mode='wrap') as 1st line in the rolling_window() definition – alessandro Feb 05 '16 at 10:53
  • That's a good idea; I've edited my post to use it. Since Erik Rigtorp's "rolling_window" has been cited frequently on SO, I've given the circular version a different name. – unutbu Feb 05 '16 at 11:04