I have a series of points (x,y) data and I want to take a scrolling window of three points. To each window I want to apply a function, basically mapping the scrolling window. How can I do this in numpy?
Asked
Active
Viewed 600 times
2
-
Are there any requirements on the function, i.e. does it have to be a pure python function (no numpy functions)? How do you want to handle the ends, i.e. should the first window only include the first element or should it start with the first three elements? – user545424 Jun 16 '19 at 23:16
-
@user545424 it should start with the first three elements – Stefano Borini Jun 16 '19 at 23:16
2 Answers
1
The fastest way I think you can do something like this is to just make three copies of the array all offset by one with respect to each other. For example:
In [1]: a = np.arange(12)
In [2]: a
Out[2]: array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
In [3]: np.vstack((a,np.roll(a,-1),np.roll(a,-2))).T[:-2]
Out[3]:
array([[ 0, 1, 2],
[ 1, 2, 3],
[ 2, 3, 4],
[ 3, 4, 5],
[ 4, 5, 6],
[ 5, 6, 7],
[ 6, 7, 8],
[ 7, 8, 9],
[ 8, 9, 10],
[ 9, 10, 11]])
and then you can just operate on the last axis with your function. For example, to compute the rolling sum:
def window_function(a):
return np.sum(a,axis=-1)
>>> a = np.arange(12)
>>> map(window_function,[a[i:i+3] for i in range(len(a)-2)])
[3, 6, 9, 12, 15, 18, 21, 24, 27, 30]
>>> window_function(np.vstack((a,np.roll(a,-1),np.roll(a,-2))).T[:-2])
array([ 3, 6, 9, 12, 15, 18, 21, 24, 27, 30])
This could be generalized with a function:
def get_rolling_window(a,size):
return np.vstack(np.roll(a,-i) for i in range(size)).T[:-size+1]

user545424
- 15,713
- 11
- 56
- 70
-
ok, so you are telling me that there's no native functionality in numpy/scipy to do so – Stefano Borini Jun 16 '19 at 23:21
-
No, I don't think so. There may be specialized functions in scipy for computing rolling averages, etc. but I don't know of anything for general functions. – user545424 Jun 16 '19 at 23:24
-
Also, I just found this question https://stackoverflow.com/questions/6811183/rolling-window-for-1d-arrays-in-numpy which seems to be the same as what you're asking and the answer has an even better technique than mine for constructing the 2D array. – user545424 Jun 16 '19 at 23:24
-
I find it shocking that scipy manual is 2500 pages long, and somehow this functionality is not there – Stefano Borini Jun 16 '19 at 23:26
-
See the discussion here: https://github.com/numpy/numpy/issues/7753. Essentially, I think that if you *don't* essentially just turn the problem into a normal array operation by stacking the arrays it's going to be very inefficient and you might as well just do the for loop in python. – user545424 Jun 16 '19 at 23:28
-
Just for my personal enrichment, how is people suppose to learn and keep track of numpy/scipy/matplotlib. The amount of material is insane. It would take years for someone to become proficient in what's available. – Stefano Borini Jun 16 '19 at 23:36
-
-
Lucky you that you could focus on becoming good at one thing for 10 years. – Stefano Borini Jun 16 '19 at 23:44
-
@StefanoBorini I began learning English at least 15 years ago. Still occasionally feeling the pain of "I'm never going to be as good as a native speaker". – Imperishable Night Jun 17 '19 at 00:47
0
There is one method so called convolve
in numpy
, for example if you need sum
n=3
np.convolve(a, np.ones((n,)), mode='valid')
array([ 3., 6., 9., 12., 15., 18., 21., 24., 27., 30.])

BENY
- 317,841
- 20
- 164
- 234