這個問題類似於this之一。numpy 2d布爾數組索引與沿一個軸減少
我有一個2d布爾數組「屬於」和一個2d浮點數組「角度」。 我想要的是在行中求和屬於的對應索引的角度爲True,並且用numpy(即避免python循環)做到這一點。我不需要存儲結果行,它們會有不同的長度,正如鏈接問題中所解釋的那樣,需要一個列表。
所以我嘗試的是np.sum(角度[屬於],軸= 1),但角度[屬於]返回1d結果,我不能減少它,因爲我想要的。我也試過np.sum(角度*屬於,軸= 1),並且工作。但我想知道是否可以通過只訪問屬於True的索引來改進時間。屬於真實約30%的時間和角度是一個涉及角度的較長公式的簡化。
UPDATE
我喜歡einsum的解決方案,但是在我的實際運算速度可達很小。我用問題中的角度來簡化,實際上它是一個使用角度的公式。我懷疑這個公式是針對所有角度計算的(不管屬於哪個角度),然後傳遞給執行計算的einsum。
這是我做了什麼:
THRES_THETA和MAX_LINE_LENGTH是浮動。 屬於,角度和lines_lengths_vstacked具有形狀(1653,58) 和np.count_nonzero(屬於)/belong.size - > 0.376473287856979
l2 = (lambda angle=angle, belong=belong, THRES_THETA=THRES_THETA, lines_lengths_vstacked=lines_lengths_vstacked, max_line_length=max_line_length:
np.sum(belong*(0.3 * (1-(angle/THRES_THETA)) + 0.7 * (lines_lengths_vstacked/max_line_length)), axis=1)) #base method
t2 = timeit.Timer(l2)
print(t2.repeat(3, 100))
l1 = (lambda angle=angle, belong=belong, THRES_THETA=THRES_THETA, lines_lengths_vstacked=lines_lengths_vstacked, max_line_length=max_line_length:
np.einsum('ij,ij->i', belong, 0.3 * (1-(angle/THRES_THETA)) + 0.7 * (lines_lengths_vstacked/max_line_length)))
t1 = timeit.Timer(l1)
print(t1.repeat(3, 100))
l3 = (lambda angle=angle, belong=belong:
np.sum(angle*belong ,axis=1)) #base method
t3 = timeit.Timer(l3)
print(t3.repeat(3, 100))
l4 = (lambda angle=angle, belong=belong:
np.einsum('ij,ij->i', belong, angle))
t4 = timeit.Timer(l4)
print(t4.repeat(3, 100))
,結果是:
[0.2505458095931187, 0.22666162878242901, 0.23591678551324263]
[0.23295411847036418, 0.21908727226505043, 0.22407296178704272]
[0.03711204915708555, 0.03149960399994978, 0.033403337575027114]
[0.025264803208228992, 0.022590580646423053, 0.024585736455331464]
如果我們看一下在最後兩行中,對應於Einsum的那個比使用基本方法快大約30%。但是如果我們看一下前兩行的話,那麼艾索姆法的加速比較小,大約快0.1%。
我不確定這個時間是否可以改善。
感謝您的回答。艾森豪斯的方法看起來非常有趣。然而,在實際計算中,我使用einsum vs based的速度增益很小。我認爲這可能是因爲不是角度而是我有一個更大的操作,無論如何對於整個矩陣必須進行計算,然後才進入艾斯法姆。我將編輯我的問題,以顯示我的測試結果與真實性以及涉及角度的實際公式 – martinako