2013-04-26 56 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