2011-09-19 38 views
3

假设我有一个数组A.我有一系列索引对(A1,B1),(A2,B2)......(一个,BN)numpy的总和在子阵列对指数之间

我想获得这些对之间所有元素的总和。即

sum(A[a1:b1]), sum(A[a2:b2]), sum(A[a3:b3]) ... 

就运行时间而言,最有效的方法是什么?

谢谢!

回答

8

假设你的指数对存储在一个与NumPy阵列形状(n, 2)nindices是相当大的,它可能是最好的,以避免任何的Python循环:

c = numpy.r_[0, A.cumsum()][indices] 
sums = c[:,1] - c[:,0] 
+1

非常好... :) – unutbu

+0

谢谢,这帮了我很多。 – Plamen

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也可以使用。

0

在第一种情况下我会尝试直接的解决方案:

[np.sum(A[a:b]) for (a,b) in ab] 

其中ab是对的序列。

A[a:b]在数组上创建一个视图;没有涉及的数据的复制。

如果这被证明是过于缓慢,请详细介绍一下A的大小,多少对指数如何你希望得到的(a,b)范围是否趋于重叠在一起,等

0

这里的另一种方式:

 
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如果有很多索引可能会更高效。