两个数组中相应列表的外积之和 - NumPy

时间:2016-11-15 14:58:24

标签: python performance numpy for-loop vectorization

我正在尝试找到numpy矩阵运算,以获得与以下for循环代码相同的结果。我相信它会快得多,但我缺少一些python技能。

它逐行工作,x行中的每个值乘以e中同一行的每个值,然后求和。

第一项结果是(2 * 0 + 2 * 1 + 2 * 4 + 2 * 2 + 2 * 3)+(0 * 0 + ...)+ ... +(1 * 0 + 1 * 1 + 1 * 4 + 1 * 2 + 1 * 3)= 30

任何想法都会非常感激:)。

e = np.array([[0,1,4,2,3],[2,0,2,3,0,1]])
x = np.array([[2,0,0,0,1],[0,3,0,0,4,0]])
result = np.zeros(len(x))
for key, j in enumerate(x):
    for jj in j:
        for i in e[key]:
            result[key] += jj*i
>>> result
Out[1]: array([ 30.,  56.])

2 个答案:

答案 0 :(得分:1)

那些是不规则的数组,因为它们有不同长度的列表。因此,即使可能,完全矢量化的方法也不会是直截了当的。这是在循环理解中使用np.einsum的一个 -

[np.einsum('i,j->',x[n],e[n]) for n in range(len(x))]

示例运行 -

In [381]: x
Out[381]: array([[2, 0, 0, 0, 1], [0, 3, 0, 0, 4, 0]], dtype=object)

In [382]: e
Out[382]: array([[0, 1, 4, 2, 3], [2, 0, 2, 3, 0, 1]], dtype=object)

In [383]: [np.einsum('i,j->',x[n],e[n]) for n in range(len(x))]
Out[383]: [30, 56]

如果您仍然对完全向量化方法感到执着,则可以创建一个常规数组,其中较小的列表将填充为零。同样,这里有一个post列出了基于NumPy的方法来填充。

有一次,我们将常规形状的数组设为xe,最终结果就是 -

np.einsum('ik,il->i',x,e)

答案 1 :(得分:0)

这接近你想要的吗?

https://docs.scipy.org/doc/numpy/reference/generated/numpy.dot.html

看起来你正试图获得矩阵的点积。