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

时间:2015-07-09 13:49:34

标签: python numpy

我有一组带有月度数据的一维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 __

2 个答案:

答案 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的实现可能会使该解决方案的任何好处都不存在。