假設我有一個數組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