【问题标题】:Python - fast way to sum outer products?Python - 对外部产品求和的快速方法?
【发布时间】:2013-07-02 23:40:33
【问题描述】:

我正在寻找一种快速计算 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) 将其相加。但是,这很慢,我想知道是否有一个矢量化函数可以用来加快速度。

如果有人有任何建议,我将不胜感激!

【问题讨论】:

    标签: python numpy scipy


    【解决方案1】:

    在我看来,您需要做的就是改变换位的顺序,并使用A.T * B 而不是A * B.T

    如果这不是您所追求的,请查看np.einsum,它可以做一些非常强大的巫术。对于上面的例子,你会这样做:

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

    【讨论】:

      【解决方案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 广播成功。

      【讨论】:

      • 他正在乘以 np.matrix 对象,而不是 np.ndarrays。然后A * B.T 等价于np.dot(A, B.T)A.T * B 等价于np.dot(A.T, B)。它的时钟应该非常非常接近np.einsum
      • +1 用于在两种方法之间进行很好的比较
      猜你喜欢
      • 2014-10-17
      • 1970-01-01
      • 1970-01-01
      • 2018-11-23
      • 1970-01-01
      • 2016-10-01
      • 1970-01-01
      • 2018-03-28
      • 1970-01-01
      相关资源
      最近更新 更多