在索引对之间的子阵列中的Numpy值

时间:2011-09-19 13:10:00

标签: python numpy sum

假设我有一个数组A.我有一系列索引对(a1,b1),(a2,b2)......(an,bn)

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

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

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

谢谢!

4 个答案:

答案 0 :(得分:8)

假设您的索引对存储在形状indices的NumPy数组(n, 2)中且n相当大,那么最好避免任何Python循环:

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

答案 1 :(得分:1)

这是另一种方式:

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可能会更有效率。

答案 2 :(得分: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

答案 3 :(得分:0)

在第一个例子中,我尝试直接解决方案:

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

其中ab是对的序列。

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

如果结果太慢,请告诉我们更多关于A的大小,您希望获得多少对索引,(a,b)范围是否会重叠等等。