我正在寻找一种方法来实现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)
答案 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]
进化阵列是什么意思?