python - "np.cumsum() like"- 根据实际值迭代

标签 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],不同之处在于它仅对原始数组的值求和,而不是对演化数组的值求和。

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

@编辑:

为了把事情说清楚:

对于一维数组,循环给出

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

与累积:

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

对于二维,它会给出类似的内容:

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

最佳答案

如果计算出循环的结果,请从序列 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])

但总的来说,我担心您将不得不保留循环。

关于python - "np.cumsum() like"- 根据实际值迭代,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15466287/

相关文章:

r - 使用 dplyr mutate 的唯一值的 cumsum

python - 使用matplotlib subplot排列饼图

python - 在一个文件中搜索第二个文件中的字符串

python - 谷歌应用引擎代理

python - 如何从 9 个大小为 N 的数组快速创建 N 个 3x3 矩阵的数组?

python - R-Python : Getting Monthly, 每周索引点

python - Cython:创建返回数组的 C 函数

python - 在 Python 中读取原始二进制图像

R:计算自上次出现值以来的累计和和计数