“np.cumsum()喜欢” - 迭代,实际值

时间:2013-03-17 21:10:50

标签: python numpy cumsum

我正在寻找一种方法来实现numpy这段python代码:

  N = np.arange(5)

  for i in range(5):
     for k in range(i):
        N[i] += N[k]

假设我实际上在大二维阵列(1300 * 1300)上工作。

np.cumsum()在一个轴N[0][i]N[i][0]上提供了一个好方法,除了它只对原始数组的值进行求和,而不是对进化数组的值进行求和。

我无法想办法做到这一点。有什么想法吗?

@Edit:

说清楚:

使用1-D数组,循环给出

Out[89]: array([ 0,  1,  3,  7, 15])

用cumsum:

array([ 0,  1,  3,  6, 10])

使用2-D,它会给出类似的东西:

N = np.arange(25).reshape(5,5)
for i in range(len(N)):
    N = np.cumsum(N, axis=i)

2 个答案:

答案 0 :(得分:2)

如果计算出循环的结果,从序列a[n]开始,两个for循环的结果是序列b[n],那么:

b[n] = a[n] + a[n-1] + 2*a[n-2] + 4*a[n-3] + ... + 2**(n-2)*a[0] =
       a[n] + c[n-1] 

我在哪里定义:

c[n-1] = a[n-1] + 2*a[n-2] + 4*a[n-3] + ... + 2**(n-2)*a[0]

考虑到最后一个表达式,有一些方法可以对双循环进行矢量化。但请注意非常大的因子(2**(n-2)),您必须将序列中的项目相乘。如果您的序列有正面和负面的术语,这些可能会取消并返回合理的数字。但是如果你有一个超过1000个正元素的数组,那么你将溢出任何numpy dtype。

因此,对于少于30个项目的短序列,如果强制使用int64,则可能为60个,以下内容比for循环更快:

def evolving_cumsum(arr):
    arr = np.array(arr) # makes a copy of the data
    pows = 2**np.arange(len(arr))[::-1]
    c = np.cumsum(arr*pows)
    c /= pows
    arr[1:] += c[:-1]
    return arr

>>> a = np.arange(10)
>>> evolving_cumsum(a)
array([  0,   1,   3,   7,  15,  31,  63, 127, 255, 511])
>>> for i in range(len(a)):
...     for k in range(i):
...         a[i] += a[k]
... 
>>> a
array([  0,   1,   3,   7,  15,  31,  63, 127, 255, 511])

但总的来说,我担心你必须保持你的循环。

答案 1 :(得分:0)

import numpy as np
N = np.arange(5)
print np.cumsum(N) # outputs [ 0  1  3  6 10]

for i in range(5):
    for k in range(i):
        N[i] += N[k]

print np.cumsum(N) # outputs [ 0  1  4 11 26]

进化阵列是什么意思?