Python Running a sum with a given window

I want to create a numpy array, which is the cumulative sum of another numpy array given by a specific window.

For example, if an array is given [1,2,3,4,5,6,7,8,9,10,11,12] , let's say I want the total amount with window 3. What I want is out put , will be [1,3,6,9,12,15,18,21,24,27,30,33] . I have a relatively large numpy array and would like to make a cumulative sum with a 400 window.

+3
source share
4 answers
 In [42]: lis=[1,2,3,4,5,6,7,8,9,10,11,12] In [43]: w=3 #window size In [44]: [sum(lis[i-(w-1):i+1]) if i>(w-1) else sum(lis[:i+1]) for i in range(len(lis))] Out[44]: [1, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33] In [45]: w=4 In [46]: [sum(lis[i-(w-1):i+1]) if i>(w-1) else sum(lis[:i+1]) for i in range(len(lis))] Out[46]: [1, 3, 6, 10, 14, 18, 22, 26, 30, 34, 38, 42] 

for python 2.4 or less, modify the ternary operator:

(falseValue, trueValue)[condition] instead of trueValue if condition else falseValue

 [(sum(lis[:i+1]),sum(lis[i-(w-1):i+1]))[i>(w-1)] for i in range(len(lis))] 
+3
source

Here is perhaps a simpler answer based on subtracting the offset cumsums.

 >>> a = np.array([1,2,3,4,5,6,7,8,9,10,11,12]) >>> b = a.cumsum() >>> b[3:] = b[3:] - b[:-3] >>> b array([ 1, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33]) 
+17
source

You should probably use numpy if you really don't need speed (although I would prefer it anyway). This way you can use methods based on convolve or stride_tricks (they are not obvious, but are well versed in these things).

For example, for such a function (you can also find more and more interesting versions):

 def embed(array, dim, lag=1): """Create an embedding of array given a resulting dimension and lag. The array will be raveled before embedding. """ array = np.asarray(array) array = array.ravel() new = np.lib.stride_tricks.as_strided(array, (len(array)-dim*lag+lag, dim), (array.strides[0], array.strides[0]*lag)) return new 

You can do:

 embedded = embed(array, 400) result = embedded.sum(1) 

What kind of memory efficiency (embedding or something else that you call creates only a view) and fast. Another approach, of course, would be to use convolve:

 np.convolve(array, np.ones(400), mode='valid') 

I don’t know if you also want incomplete windows, it will be the same as using mode='full' (default) for convolve. For another approach, this must be handled in some other way.

+7
source

seberg's answer is better and more general than mine, but note that you need to reset your samples to get the desired result.

 import numpy as np from numpy.lib.stride_tricks import as_strided as ast samples = 100 window = 3 padding = np.zeros(window - 1) # zero-pad your samples a = np.concatenate([padding,np.arange(1,samples + 1)]) newshape = (len(a) - window,window) newstrides = a.strides * 2 # this gets you a sliding window of size 3, with a step of 1 strided = ast(a,shape = newshape,strides = newstrides) # get your moving sum strided.sum(1) 
+1
source

Source: https://habr.com/ru/post/1447662/


All Articles