ben olsen ben olsen - 7 months ago 27
Python Question

numpy.convolve python old numbers cant change

I am working with numpy.convolve . To be honest I am not sure if I am using the correct module for the project I am working.
Question:
I want numpy convolve (or if there is any other module I can implement) not to change previous numbers. To add. I dont want the old numbers changed I want them to be fixed. So when I get new data the only number that should be affect is the new one, not the rest.

Here is an example: (to clarify it better.)

import numpy

N = 3
numbers = [11,-5,54,-100,1]
numbers_mean = numpy.convolve(numbers, numpy.ones((N,))/N)[(N-1):]
print numbers_mean


Output:

[ 20. -17. -15. -33. 0.33333333]


BUT
When I change the last number to 100 instead of 1 the result changes all 3 numbers.

N = 3
numbers = [11,-5,54,-100,100]
numbers_mean = numpy.convolve(numbers, numpy.ones((N,))/N)[(N-1):]
print numbers_mean


Output:

[ 20. -17. 18. 0. 33.33333333]


JUST THE OUTPUTS:
.
.

[ 20. -17. -15. -33. 0.33333333]
[ 20. -17. 18. 0. 33.33333333]


THIS IS WHAT I WANT TO SEE:

[ 20. -17. -15. -33. 33.33333333<- this number only should change not the rest]


So as you can see when the number goes from 1 to 100 it changed the -33. to 0. this is not what I want I want all of those numbers to be fixed and none changing the only number that should be able to change is the newest number. in this case 33.333333 from 0.3333

Is there any module or way I can implant this in python.

Thank you

Answer

IIUC, you want to compute 3-neighborhood means. So you have a mask=[1./3,1./3,1./3] which size is N.

See what happen on a simpler example , numbers = [0,1,2,3,4] , which size is M>=N :

In [1]: numpy.convolve(numbers,mask)
Out[1]: 
array([ 0.        ,  0.33333333,  1.        ,  2.        ,  3.        ,
        2.33333333,  1.33333333])

This is an array with N+M-1 elements . There are only M-2(N-1) valid means, [1,2,3] here, and N-1 overlapping means at the beginning and at the END : You must discard them too.

For your case :

N = 3
a1 = [11,-5,54,-100,1]
a2 = [11,-5,54,-100,100]

mask=numpy.ones(N)/N
m1= numpy.convolve(a1, mask)[(N-1):-(N-1)]
m2= numpy.convolve(a2, mask)[(N-1):-(N-1)]
print (m1,m2)

# [ 20. -17. -15.] [ 20. -17.  18.]

Only the last term is affected.

EDIT

  • To avoid the N-1 last terms, an other approach is to use scipy.signal.lfilter, which implement differences equations :

Here, mean(n) - mean(n-1) = data(n)/N -data(n-N)/N .

from scipy.signal import lfilter
N=3
a=np.array([1,-1])
b=np.concatenate(([1],np.zeros(N-1),[-1]))/N
x=np.arange(5)
means=lfilter(b,a,x)
# array([0.,0.3333,1.,2.,3.])