【问题标题】:Multidimensional numpy.outer without flatten多维 numpy.outer 没有展平
【发布时间】:2019-11-23 17:06:41
【问题描述】:

x 是 N × M 矩阵。

y 是 1 乘 L 向量。

我想返回 x 和 y 之间的“外积”,我们称之为 z。

z[n,m,l] = x[n,m] * y[l]

我或许可以使用 einsum 做到这一点。

np.einsum("ij,k->ijk", x[:, :, k], y[:, k])

或之后再整形。

 np.outer(x[:, :, k], y).reshape((x.shape[0],x.shape[1],y.shape[0]))

但我正在考虑仅在 np.outer 中执行此操作,或者看起来更简单,内存效率更高。

有办法吗?

【问题讨论】:

    标签: numpy matrix linear-algebra matrix-multiplication


    【解决方案1】:

    outer 的代码是:

    multiply(a.ravel()[:, newaxis], b.ravel()[newaxis, :], out)
    

    正如其文档所说,它变平(即ravel)。如果数组已经是 1d,则该表达式可以写为

    a[:,None] * b[None,:]
    a[:,None] * b        # broadcasting auto adds the None to b
    

    我们可以将广播规则应用于您的 (n,m)*(1,l):

    In [2]: x = np.arange(12).reshape(3,4); y = np.array([[1,2]])                                                
    In [3]: x.shape, y.shape                                                                                     
    Out[3]: ((3, 4), (1, 2))
    

    你想要一个 (n,m,l),这是 (n,m,1) * (1,1,l) 实现的。我们需要向x 添加一个尾随维度。 y 上的额外前导 1 是自动的:

    In [4]: z = x[...,None]*y                                                                                    
    In [5]: z.shape                                                                                              
    Out[5]: (3, 4, 2)
    In [6]: z                                                                                                    
    Out[6]: 
    array([[[ 0,  0],
            [ 1,  2],
            [ 2,  4],
            [ 3,  6]],
    
           [[ 4,  8],
            [ 5, 10],
            [ 6, 12],
            [ 7, 14]],
    
           [[ 8, 16],
            [ 9, 18],
            [10, 20],
            [11, 22]]])
    

    使用einsum

    In [8]: np.einsum('nm,kl->nml', x, y).shape                                                                  
    Out[8]: (3, 4, 2)
    

    您批准的事实:

    In [9]: np.multiply.outer(x,y).shape                                                                         
    Out[9]: (3, 4, 1, 2)
    

    建议 y 不是真正的 (1,l) 而是 (l,)`。调整任何一个都很容易。

    我认为这些之间的内存效率没有太大差异。在这个小例子中,In[4] 是最快的,但不是很多。

    【讨论】:

      【解决方案2】:

      这是numpy“除非你碰巧知道否则无法知道”位之一:np.outer 使多维输入变平,而np.multiply.outer 则不:

      m,n,l = 3,4,5
      x = np.arange(m*n).reshape(m,n)
      y = np.arange(l)
      np.multiply.outer(x,y).shape
      # (3, 4, 5)
      

      【讨论】:

        猜你喜欢
        • 2021-03-27
        • 2012-08-27
        • 2020-06-06
        • 2021-06-19
        • 1970-01-01
        • 2011-09-05
        • 2010-11-22
        • 1970-01-01
        相关资源
        最近更新 更多