假设我有一个数组A.我有一系列索引对(A1,B1),(A2,B2)......(一个,BN)numpy的总和在子阵列对指数之间
我想获得这些对之间所有元素的总和。即
sum(A[a1:b1]), sum(A[a2:b2]), sum(A[a3:b3]) ...
就运行时间而言,最有效的方法是什么?
谢谢!
假设我有一个数组A.我有一系列索引对(A1,B1),(A2,B2)......(一个,BN)numpy的总和在子阵列对指数之间
我想获得这些对之间所有元素的总和。即
sum(A[a1:b1]), sum(A[a2:b2]), sum(A[a3:b3]) ...
就运行时间而言,最有效的方法是什么?
谢谢!
假设你的指数对存储在一个与NumPy阵列形状(n, 2)
和n
的indices
是相当大的,它可能是最好的,以避免任何的Python循环:
c = numpy.r_[0, A.cumsum()][indices]
sums = c[:,1] - c[:,0]
如果你有很多索引对,并且你的数组很长,那么缓存可能是一个选项。我会尝试一个递归的方法,如
CACHE = {}
def mysum(a, b):
if (a, b) in CACHE:
return CACHE[(a, b)]
if a >= b:
return 0
s = A[a] + mysum(a+1, b)
CACHE[(a, b)] = s
return s
虽然没有检查正确性或效率。减少上限指数b
也可以使用。
在第一种情况下我会尝试直接的解决方案:
[np.sum(A[a:b]) for (a,b) in ab]
其中ab
是对的序列。
A[a:b]
在数组上创建一个视图;没有涉及的数据的复制。
如果这被证明是过于缓慢,请详细介绍一下A
的大小,多少对指数如何你希望得到的(a,b)
范围是否趋于重叠在一起,等
这里的另一种方式:
a = np.random.rand(3000) indices = np.array([[0,3], [9,20], [5,30], [9,33]]) sums = np.add.reduceat(a, indices.ravel())[::2] assert np.all(sums == np.array([a[i:j].sum() for i,j in indices]))
上面的cumsum
如果有很多索引可能会更高效。
非常好... :) – unutbu
谢谢,这帮了我很多。 – Plamen