【问题标题】:Faster alternative to numpy.einsum for taking the "element-wise" dot product of two lists of vectors?更快地替代 numpy.einsum 来获取两个向量列表的“元素方式”点积?
【发布时间】:2014-06-16 06:21:08
【问题描述】:

假设你有两个向量数组:

v1 = np.array([ [1, 2], [3, 4] ]) v2 = np.array([ [10, 20], [30, 40]])

我们想生成一个等价于的数组:

v3 = np.array([ np.dot(v1[0], v2[0]), np.dot(v1[1], v2[1]) ])

目前我使用:

v3 = np.einsum('ij,ij->i', v1, v2)

但是,我在我的代码中经常这样做,所以这里的加速对我很有帮助。

我们怎样才能加快速度? np.einsum 已经相当高效了,但我想知道对于这个特殊的用例,是否有更快的方法?

【问题讨论】:

标签: python numpy


【解决方案1】:

einsum 做了我能想到的 3 个选项中最好的:

In [73]: timeit v3=np.einsum('ij,ij->i',v1,v2)
100000 loops, best of 3: 5.14 us per loop

In [74]: timeit np.diag(np.dot(v1,v2.T))
100000 loops, best of 3: 7.43 us per loop

In [75]: timeit np.sum(v1*v2,axis=1)
100000 loops, best of 3: 16.8 us per loop

要问的几个问题:

  • 这个计算真的那么贵吗?
  • 如果相对昂贵,您是否必须经常这样做?
  • 你能合并einsum 调用 - 连接数组吗?

【讨论】:

【解决方案2】:

试试inner1d

import numpy as np
import cProfile
from numpy.core.umath_tests import inner1d

v1 = np.random.random((10**7,2,))  # 10 million random vectors
v2 = np.random.random((10**7,2,))  # 10 million random vectors
v3 = np.einsum('ij,ij->i', v1, v2) # einsum
v4 = inner1d(v1,v2)                # inner1d (~2x faster than einsum)

cProfile.run("np.einsum('ij,ij->i', v1, v2)") # cProfile: 3 function calls in 0.065 seconds
cProfile.run("inner1d(v1,v2)") # cProfile: 2 function calls in 0.033 seconds

print np.allclose(v3,v4) # Returns True

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-27
    • 1970-01-01
    • 1970-01-01
    • 2017-03-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多