【问题标题】:How to vectorize an operation between a 2D array and another vector?如何向量化二维数组和另一个向量之间的操作?
【发布时间】:2020-05-05 11:53:43
【问题描述】:

我有一个像这样的 numpy 二维数组:

[[1, 2], [3, 4]]

还有一个像这样的单独向量: [5, 6].

本例中的操作是np.inner,这是我更大任务的一部分,即获取二维数组的每一行与单独向量之间的余弦相似度。

我的预期输出是[np.inner([1, 2], [5, 6]), np.inner([3, 4], [5, 6]]。我可以使用apply_along_axis 完成此操作,但有什么方法可以矢量化此操作并使其比apply_along_axis 更高效?

关于如何在两个二维数组的行对之间向量化这些类型的操作,有很多已回答的问题,但在这种情况下,我需要向量化一个二维数组和另一个向量之间的操作。我可以将[5, 6] 转换为[[5, 6], [5, 6]],然后以这种方式进行矢量化,但是在大规模情况下,我需要一个解决方案,我可以在操作中使用另一个矢量本身,而不是将其变成带有一堆行的二维数组副本。

【问题讨论】:

    标签: python numpy scipy vectorization cosine-similarity


    【解决方案1】:
    In [6]: A = np.array([[1,2],[3,4]]); x=np.array([5,6])                                           
    

    inner 确实适用于您的二维数组(诚然,它的文档对此有点模糊

    In [7]: np.inner(A,x)                                                                            
    Out[7]: array([17, 39])
    

    通常我们使用np.dot进行矩阵乘法,包括1d inner

    In [8]: np.dot(A,x)                                                                              
    Out[8]: array([17, 39])
    

    或在较新的numpy 中,@ 运算符,也是np.matmul

    In [9]: A@x                                                                                      
    Out[9]: array([17, 39])
    

    两者都使用 last of A 和 B` 的倒数第二个(或 x 的唯一轴)。

    你想要的两个内部计算:

    In [10]: np.inner(A[0,:],x)                                                                      
    Out[10]: 17
    In [11]: np.inner(A[1,:],x)                                                                      
    Out[11]: 39
    

    一个(2,n)数组用一个(n,)数组广播,就好了,产生一个(2,n)结果

    In [12]: A * x                                                                                   
    Out[12]: 
    array([[ 5, 12],
           [15, 24]])
    In [13]: (A * x).sum(axis=1)       # and sum on the `n` axis for inner                                                                 
    Out[13]: array([17, 39])
    

    broadcasting 具有重复行(或其他维度)的效果,但计算效率很高。

    【讨论】:

      【解决方案2】:

      听起来你需要`np.dot'

      In [3]: a = np.array([[1, 2], [3, 4]])
      
      In [4]: b = np.array([5, 6])
      
      In [5]: a.dot(b)
      Out[5]: array([17, 39])
      
      In [6]: np.inner(a[0], b)
      Out[6]: 17
      
      In [7]: np.inner(a[1], b)
      Out[7]: 39
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-08-06
        • 2012-08-05
        • 2015-09-07
        • 1970-01-01
        • 2016-08-29
        • 1970-01-01
        相关资源
        最近更新 更多