我有一组带有月度数据的一维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 __
答案 0 :(得分:3)
你可以使用重塑(假设你的数组的大小是x的倍数):
sumeveryxrows = lambda myarray, x: myarray.reshape((myarray.shape[0] / x, x)).sum(1)
对于.3s
值的数组,上述内容小于30000000
:
>>> 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}
答案 1 :(得分:0)
另一种解决方案可能是
def sumeveryxrows(myarray, x):
return [sum(myarray[n: n+x]) for n in xrange(0, len(myarray), x)]
这是for 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的实现可能会使该解决方案的任何好处都不存在。