2013-04-26 52 views
2

我有一個像np.arrays的名單:多個陣列tensordot

l = [array([0.2,0.3,0.5]),array([0.7,0.3])] 

我需要得到外部產品:

array([[0.14, 0.06], 
     [0.21, 0.09], 
     [0.35, 0.15]]) 
一般方式

array([[l[0][0] * l[1][0], l[0][0] * l[1][1]], 
     [l[0][1] * l[1][0], l[0][1] * l[1][1]], 
     [l[0][2] * l[1][0], l[0][2] * l[1][1]]]) 

但是對於任何長度的l(> = 2),所以當len(l)== 4時,我會得到4維數組。

我目前的做法是使用tensordot for循環:

product = np.tensordot(l[0], l[1], 0) 
for i in range(2, len(l)): 
    product = np.tensordot(product, l[i], 0) 

但我已經習慣了,在Python代碼看起來更好。有誰想法如何做更好更快的解決方案?

的動機是,我需要逐元素的總和乘以兩個數組:

result = np.sum(arr * product) 

其中arr.shape == product.shape。也許你,聰明的人,也可以改善它。

回答

2

也許更簡潔是:

reduce(lambda x, y: tensordot(x, y, 0), l) 
+0

如果您要立即命名lambda函數,爲什麼要使它成爲lambda?唯一真正的優勢是內聯它的能力。 – DSM 2013-04-26 21:15:38

+0

是的 - 出於某種原因,我開始寫作思考一個班輪將是太長,不可見。編輯。 – YXD 2013-04-26 21:19:45

+0

我沒有這樣想過,謝謝。我可能會用這個,它絕對漂亮,速度一樣。 – Artimi 2013-04-26 21:27:47

0

numpy的有一個名爲broadcasting一個偉大的事情,它通過陣列迭代。所以如果你有一個x乘以1的數組並乘以一個y爲1的數組,你將得到一個x乘y的數組。像矩陣一樣工作。所以我打算只用兩行來做你想做的一切:

result = np.array((l[0])).reshape((1,len(l[0])))# resizing the first column to make it a 3 by 1 so that numpy broadcasting will work. 
print result * l[1] # broadcasting the 3 by 1 by a 1 by 2 to result in your 3 by 2 

那你有它!快捷方便!爲了您的方便,我將在下面放置整個代碼:

import numpy as np 
l = [([0.2,0.3,0.5]),([0.7,0.3])] 
result = np.array((l[0])).reshape((len(l[0]),1)) 
print result * l[1] 
>>>>aray([[ 0.14 0.06] 
[ 0.21 0.09] 
[ 0.35 0.15]]) 
+0

我認爲OP已經知道'outer'或'tensordot'可以很容易地處理長度爲2的情況,並且正在尋找一種更簡潔的方式來處理'l'具有任意長度的情況。 – DSM 2013-04-27 12:47:43

+0

帝斯曼是正確的。對不起,如果我寫混淆的方式,但len(l)== 2只是例子。我需要它,就像對任意長度所說的那樣。 – Artimi 2013-04-27 19:28:21