2011-09-19 26 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如果有很多索引可能會更高效。