A是一个((d,e))numpy数组。我计算一个((d,e))numpy数组B,其中我按以下方式计算条目B [i,j]
b=0
for k in range(i+1,d):
for l in range(j+1,e):
b=b+A[k,l]
B[i,j]=b
换句话说,B [i,j]是所有索引k> i,l> j的A [k,l]之和;这与应用于两个轴的通常的总和相反。我想知道是否有更优雅,更快捷的方法(例如使用np.cumsum)?
最佳答案
假设您正在尝试这样做:
A = np.arange(15).reshape((5, -1))
def cumsum2_reverse(arr):
out = np.empty_like(arr)
d, e = arr.shape
for i in xrange(d):
for j in xrange(e):
b = 0
for k in xrange(i + 1, d):
for l in xrange(j + 1, e):
b += arr[k, l]
out[i, j] = b
return out
那你去做
In [1]: A_revsum = cumsum2_reverse(A)
In [2]: A_revsum
Out[2]:
array([[72, 38, 0],
[63, 33, 0],
[48, 25, 0],
[27, 14, 0],
[ 0, 0, 0]])
您可以在逆序数组上使用
np.cumsum
来计算总和。例如,起初您可以尝试类似于@Jaime建议的操作:In [3]: np.cumsum(np.cumsum(A[::-1, ::-1], 0), 1)[::-1, ::-1]
Out[3]:
array([[105, 75, 40],
[102, 72, 38],
[ 90, 63, 33],
[ 69, 48, 25],
[ 39, 27, 14]])
在这里,我们记得
np.cumsum
从第一列(在本例中为最后一列)中的值开始,因此要确保此处为零,可以移动此操作的输出。可能看起来像:def cumsum2_reverse_alt(arr):
out = np.zeros_like(arr)
out[:-1, :-1] = np.cumsum(np.cumsum(arr[:0:-1, :0:-1], 0), 1)[::-1, ::-1]
return out
这给出与上面相同的值。
In [4]: (cumsum2_reverse(A) == cumsum2_reverse_alt(A)).all()
Out[4]: True
请注意,对于大型阵列,使用
np.cumsum
的磁盘要快得多。例如:In [5]: A=np.arange(3000).reshape((50, -1))
In [6]: %timeit cumsum2_reverse(A)
1 loops, best of 3: 453 ms per loop
In [7]: %timeit cumsum2_reverse_alt(A)
10000 loops, best of 3: 24.7 us per loop
关于python - numpy的逆累积,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31708151/