Mean of n values within an array
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@gmail.com> wrote:
On 7/29/06, Charles R Harris <charlesr.harris@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
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@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@gmail.com> wrote:
On 7/29/06, Charles R Harris <charlesr.harris@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@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/numpy-discussion
participants (2)
-
Charles R Harris -
Phil Ruggera