[Numpy-discussion] Mean of n values within an array

Charles R Harris charlesr.harris at gmail.com
Thu Aug 3 10:38:25 CDT 2006


Heh,

This is fun. Two more variations with 1000 reps instead of 100 for better
timing:

def numpy_nmean_conv_nl_tweak1(list,n):
   b = numpy.ones(n,dtype=float)
   a = numpy.convolve(list,b,mode="full")
   a[:n] /= numpy.arange(1, n + 1)
   a[n:] /= n
   return a[:len(list)]

def numpy_nmean_conv_nl_tweak2(list,n):
   b = numpy.ones(n,dtype=float)
   a = numpy.convolve(list,b,mode="full")
   a[:n] /= numpy.arange(1, n + 1)
   a[n:] *= 1.0/n
   return a[:len(list)]

Which gives

numpy convolve took: 2.630000 sec.
numpy convolve noloop took: 0.320000 sec.
numpy convolve noloop tweak1 took: 0.250000 sec.
numpy convolve noloop tweak2 took: 0.240000 sec.

Chuck

On 8/2/06, Phil Ruggera <pruggera at gmail.com> wrote:
>
> A variation of the proposed convolve routine is very fast:
>
> regular python took: 1.150214 sec.
> numpy mean slice took: 2.427513 sec.
> numpy convolve took: 0.546854 sec.
> numpy convolve noloop took: 0.058611 sec.
>
> Code:
>
> # mean of n values within an array
> import numpy, time
> def nmean(list,n):
>     a = []
>     for i in range(1,len(list)+1):
>         start = i-n
>         divisor = n
>         if start < 0:
>             start = 0
>             divisor = i
>         a.append(sum(list[start:i])/divisor)
>     return a
>
> t = [1.0*i for i in range(1400)]
> start = time.clock()
> for x in range(100):
>     reg = nmean(t,50)
> print "regular python took: %f sec."%(time.clock() - start)
>
> def numpy_nmean(list,n):
>     a = numpy.empty(len(list),dtype=float)
>     for i in range(1,len(list)+1):
>         start = i-n
>         if start < 0:
>             start = 0
>         a[i-1] = list[start:i].mean(0)
>     return a
>
> t = numpy.arange(0,1400,dtype=float)
> start = time.clock()
> for x in range(100):
>     npm = numpy_nmean(t,50)
> print "numpy mean slice took: %f sec."%(time.clock() - start)
>
> def numpy_nmean_conv(list,n):
>     b = numpy.ones(n,dtype=float)
>     a = numpy.convolve(list,b,mode="full")
>     for i in range(0,len(list)):
>         if i < n :
>             a[i] /= i + 1
>         else :
>             a[i] /= n
>     return a[:len(list)]
>
> t = numpy.arange(0,1400,dtype=float)
> start = time.clock()
> for x in range(100):
>     npc = numpy_nmean_conv(t,50)
> print "numpy convolve took: %f sec."%(time.clock() - start)
>
> def numpy_nmean_conv_nl(list,n):
>     b = numpy.ones(n,dtype=float)
>     a = numpy.convolve(list,b,mode="full")
>     for i in range(n):
>         a[i] /= i + 1
>     a[n:] /= n
>     return a[:len(list)]
>
> t = numpy.arange(0,1400,dtype=float)
> start = time.clock()
> for x in range(100):
>     npn = numpy_nmean_conv_nl(t,50)
> print "numpy convolve noloop took: %f sec."%(time.clock() - start)
>
> numpy.testing.assert_equal(reg,npm)
> numpy.testing.assert_equal(reg,npc)
> numpy.testing.assert_equal(reg,npn)
>
> On 7/29/06, David Grant <davidgrant at gmail.com> wrote:
> >
> >
> >
> > On 7/29/06, Charles R Harris <charlesr.harris at gmail.com> wrote:
> > >
> > > Hmmm,
> > >
> > > I rewrote the subroutine a bit.
> > >
> > >
> > > def numpy_nmean(list,n):
> > >     a = numpy.empty(len(list),dtype=float)
> > >
> > >     b = numpy.cumsum(list)
> > >     for i in range(0,len(list)):
> > >         if i < n :
> > >             a[i] = b[i]/(i+1)
> > >         else :
> > >             a[i] = (b[i] - b[i-n])/(i+1)
> > >     return a
> > >
> > > and got
> > >
> > > regular python took: 0.750000 sec.
> > > numpy took: 0.380000 sec.
> >
> >
> > I got rid of the for loop entirely. Usually this is the thing to do, at
> > least this will always give speedups in Matlab and also in my limited
> > experience with Numpy/Numeric:
> >
> >  def numpy_nmean2(list,n):
> >
> >     a = numpy.empty(len(list),dtype=float)
> >     b = numpy.cumsum(list)
> >      c = concatenate((b[n:],b[:n]))
> >     a[:n] = b[:n]/(i+1)
> >      a[n:] = (b[n:] - c[n:])/(i+1)
> >     return a
> >
> > I got no noticeable speedup from doing this which I thought was pretty
> > amazing. I even profiled all the functions, the original, the one
> written by
> > Charles, and mine, using hotspot just to make sure nothing funny was
> going
> > on. I guess plain old Python can be better than you'd expect in certain
> > situtations.
> >
> > --
> > David Grant
>
> -------------------------------------------------------------------------
> Take Surveys. Earn Cash. Influence the Future of IT
> Join SourceForge.net's Techsay panel and you'll get the chance to share
> your
> opinions on IT & business topics through brief surveys -- and earn cash
> http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
> _______________________________________________
> Numpy-discussion mailing list
> Numpy-discussion at lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/numpy-discussion
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://projects.scipy.org/pipermail/numpy-discussion/attachments/20060803/4c69cb47/attachment-0001.html 


More information about the Numpy-discussion mailing list