繁体   English   中英

Python numpy:每3行加一次(每月转换为季度)

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM