[英]Python numpy: sum every 3 rows (converting monthly to quarterly)
我有一组带有月度数据的一维numpy数组。 我需要按季度聚合它们,创建一个新数组,其中第一项是旧数组的前3项的总和,等等。
我正在使用此函数,x = 3:
def sumeveryxrows(myarray,x):
return([sum(myarray[x*n:x*n+x]) for n in range( int(len(myarray)/x))])
它有效,但你能想到一个更快的方法吗? 我描述了它,97%的时间用于做__getitem__
您可以使用reshape(假设您的数组的大小为x的倍数):
sumeveryxrows = lambda myarray, x: myarray.reshape((myarray.shape[0] / x, x)).sum(1)
在具有30000000
值的阵列上,上述时间小于.3s
:
>>> a = numpy.random.rand(30000000)
>>> cProfile.run('sumeveryxrows(a, 3)')
8 function calls in 0.263 seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 0.258 0.258 <stdin>:1(<lambda>)
1 0.005 0.005 0.263 0.263 <string>:1(<module>)
1 0.000 0.000 0.258 0.258 _methods.py:31(_sum)
1 0.000 0.000 0.263 0.263 {built-in method exec}
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
1 0.258 0.258 0.258 0.258 {method 'reduce' of 'numpy.ufunc' objects}
1 0.000 0.000 0.000 0.000 {method 'reshape' of 'numpy.ndarray' objects}
1 0.000 0.000 0.258 0.258 {method 'sum' of 'numpy.ndarray' objects}
另一个解决方案可能是
def sumeveryxrows(myarray, x):
return [sum(myarray[n: n+x]) for n in xrange(0, len(myarray), x)]
这是为python 2.x. 如果你使用python 3用范围替换xrange。 xrange使用迭代器而不是生成整个列表。 您还可以指定一个步骤。 这消除了使用乘法的需要。
当然,总有非python方式(特别是3)。
def sumevery3rows(a):
i = 0
ret = []
stop = len(a) - 2
while i < stop:
ret.append(a[i] + a[i+1] + a[i+2])
i += 3
if i != len(a):
ret.append(sum(a[i:len(a)]))
return ret
我不知道它的表现如何,变量x的实现可能会使该解决方案的任何好处都不存在。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.