2017-07-10 40 views
1

我有一些numpy的操作,我可以在一個循環中完美執行,但我一直無法在一次numpy調用中將它們引導。Vectorise序列numpy計算

# data matrix 
d = np.random.rand(1496, 1, 2) 

# boolean matrix 
r = np.random.rand(5, 1496, 1, 2) > 0.5 

# result matrix 
x = np.empty((5,)) 

# How can I avoid this loop? 
for i in xrange(r.shape[0]): 
    x[i] = d[r[i]].sum() 

是否有可能通過某種方式來加速向上循環?

回答

1

您可以將其作爲此矢量化;因爲d是小於r的一維,所以當它們相乘時,d將沿着的進行廣播,因此避免循環;並且還因爲r是一個布爾陣列,d[r].sum()將相同(d*r).sum

(d * r).sum(axis=(1,2,3)) 
# array([ 775.17049697, 728.61537246, 735.05686655, 765.19469927, 
#   759.44834287]) 

結果是一樣x:所述@Psidom方法

((d*r).sum(axis=(1,2,3)) == x).all() 
# True 
+0

不錯的想法乘法float和布爾矩陣並使用廣播(也感謝您的解釋)。 – orange

+0

沒問題。很高興它有幫助。 – Psidom

2

的變化:

np.tensordot(d, r, axes=((0,1,2), (1,2,3))) 

這依賴於tensordot函數。從其documentation

給定兩個張量a,和b,並含有兩個array_like目的,(a_axes, b_axes)一個array_like對象(尺寸大於或等於一的陣列),總結的a的和b'產品(元件)在a_axesb_axes指定的軸上。

從根本上講,tensordot計算兩個陣列(就像@Psidom所做的那樣)的產品和計算產品陣列的所有元素的總和。這種方法與@ Psidom方法相比唯一的「優點」是它可以更靈活地指定在兩個陣列中哪些軸執行產品和求和。它不會比@ Psidom的方法提供更好的性能。

另外,參見Understanding tensordot

+0

有趣的方法。你能解釋一下嗎?這會比Psidom的建議快嗎? – orange