Python - 快速总结外部产品的方法?

时间:2013-07-02 23:40:33

标签: python numpy scipy

我正在寻找一种快速计算n种外部产品总和的方法。

基本上,我从正态分布生成的两个矩阵开始 - 有n个向量与v元素:

A = np.random.normal(size = (n, v))
B = np.random.normal(size = (n, v))

我想要的是计算A和B中每个矢量大小为v的外积并将它们加在一起。

请注意A * B.T不起作用 - A的大小为n x v,而B的大小为v x n。

我能做的最好的事情是创建一个外部产品构建的循环,然后再加总。我喜欢它:

outers = np.array([A[i] * B[i].T])

这会创建一个n x v x v数组(循环在列表解析中,随后会转换为数组),然后我可以使用np.sum(outers, axis = 0)将它们相加。然而,这很慢,我想知道是否有一个矢量化函数可以用来加速它。

如果有人有任何建议,我会非常感激!

2 个答案:

答案 0 :(得分:9)

在我看来,您需要做的就是更改换位顺序,然后A.T * B代替A * B.T

如果那不是你想要的,那么看看np.einsum,它可以做一些非常强大的伏都教。对于上面的示例,您可以执行以下操作:

np.einsum('ij,ik->jk', A, B)

答案 1 :(得分:2)

另请考虑np.outer

np.array([np.outer(A, B) for i in xrange(n)]).sum(0)

尽管@Jamie提出的np.einsum是明显的赢家。

In [63]: %timeit np.einsum('ij,ik->jk', A, B)
100000 loops, best of 3: 4.61 us per loop

In [64]: %timeit np.array([np.outer(A[i], B[i]) for i in xrange(n)]).sum(0)
10000 loops, best of 3: 169 us per loop

并且,可以肯定的是,他们的结果是相同的:

In [65]: np.testing.assert_allclose(method_outer, method_einsum)

但是,顺便说一句,我没有找到A.T * BA * B.T成功广播。