【问题标题】:How do I multiply rows in one numpy array with multiple columns in a second array?如何将一个 numpy 数组中的行与第二个数组中的多列相乘?
【发布时间】:2020-04-25 00:14:22
【问题描述】:

我有一个棘手的问题

我有一个二维值数组

vals=np.array([[1.0, 2.0, 3.0],[4.0, 5.0, 6.0],[7.0, 8.0, 9.0]], np.float32)

还有一个二维比例因子数组

factors=np.array([[1.0, 4.0], [2.0, 5.0], [3.0, 6.0]])

我想将 vals 中的每一行与因子中的每一行相乘,最终得到一个“scaled_vals”数组,如下所示 注意:此输出已从我的原始帖子中更正 - 我对这个错误表示歉意

[[ 1.  2.  3.]
 [ 8. 10. 12.]
 [21. 24. 27.]]
[[ 4.  8. 12.]
 [20. 25. 30.]
 [42. 48. 54.]]

我只用两列数据显示因子,但实际上它是“n”。

我们将不胜感激。

道格

===

从评论中复制:

for step in range(2): 
    scaled_vals = np.multiply(vals, factors[0:,step:step+1])

【问题讨论】:

  • 你能解释一下你是如何得到输出的吗?我无法通过任何乘法组合来理解它。这只是输出的第一个元素吗?
  • 使用循环为 range(2) 中的步长生成输出:scaled_vals = np.multiply(vals, factor[0:,step:step+1])
  • 现在我明白了。谢谢你的澄清。我有一个简单的单行解决方案,我在其中发布和索引,让您非常容易阅读。
  • 所有 - 我完全搞砸了我的问题 - 我很抱歉浪费了大家的时间。我实际上试图实现的输出是 [[ 1. 2. 3.] [ 8. 10. 12.] [21. 24. 27.]] [[ 4. 8. 12.] [20. 25. 30.] [42. 48. 54.]] 这就是 hpaulj 所指出的循环实际产生的结果
  • 您可以轻松地将我的帖子修改为您的设置。我稍后将根据此评论要求对其进行编辑。我想会是‘ij,ik->kij’

标签: numpy


【解决方案1】:

broadcasting

vals[:, None, None, :] * factors.T[None, :, :, None]

输出:

array([[[[ 1.,  2.,  3.],
         [ 2.,  4.,  6.],
         [ 3.,  6.,  9.]],

        [[ 4.,  8., 12.],
         [ 5., 10., 15.],
         [ 6., 12., 18.]]],


       [[[ 4.,  5.,  6.],
         [ 8., 10., 12.],
         [12., 15., 18.]],

        [[16., 20., 24.],
         [20., 25., 30.],
         [24., 30., 36.]]],


       [[[ 7.,  8.,  9.],
         [14., 16., 18.],
         [21., 24., 27.]],

        [[28., 32., 36.],
         [35., 40., 45.],
         [42., 48., 54.]]]])

【讨论】:

    【解决方案2】:

    您展示的 (2,3,3) 块可以通过以下方式生成:

    In [267]: vals[0,:]*factors.T[:,:,None]                                                                
    Out[267]: 
    array([[[ 1.,  2.,  3.],
            [ 2.,  4.,  6.],
            [ 3.,  6.,  9.]],
    
           [[ 4.,  8., 12.],
            [ 5., 10., 15.],
            [ 6., 12., 18.]]])
    

    但评论循环是;

    In [268]: for step in range(2):  
         ...:     print(np.multiply(vals, factors[0:,step:step+1])) 
         ...:                                                                                              
    [[ 1.  2.  3.]
     [ 8. 10. 12.]
     [21. 24. 27.]]
    [[ 4.  8. 12.]
     [20. 25. 30.]
     [42. 48. 54.]]
    In [269]: vals*factors.T[:,:,None]                                                                     
    Out[269]: 
    array([[[ 1.,  2.,  3.],
            [ 8., 10., 12.],
            [21., 24., 27.]],
    
           [[ 4.,  8., 12.],
            [20., 25., 30.],
            [42., 48., 54.]]])
    

    【讨论】:

      【解决方案3】:

      您可以使用einsum 一个衬里(不带循环)将您的索引乘以您想要的任何形状:

      output = np.einsum('ij,kl->ilkj',vals,factors)
      

      这会将 [i,j]vals 乘以 [k,l]factors 并将其放在输出中的 [i,l,k,j]。注意@Quan Hoang 的回答(赞成)在没有循环的情况下也是如此。但是,我认为这更具可读性,您可以将其扩展到您想要的任何其他组合。

      输出:

      [[[[ 1.  2.  3.]
         [ 2.  4.  6.]
         [ 3.  6.  9.]]
      
        [[ 4.  8. 12.]
         [ 5. 10. 15.]
         [ 6. 12. 18.]]]
      
      
       [[[ 4.  5.  6.]
         [ 8. 10. 12.]
         [12. 15. 18.]]
      
        [[16. 20. 24.]
         [20. 25. 30.]
         [24. 30. 36.]]]
      
      
       [[[ 7.  8.  9.]
         [14. 16. 18.]
         [21. 24. 27.]]
      
        [[28. 32. 36.]
         [35. 40. 45.]
         [42. 48. 54.]]]]
      

      更新:根据 cmets 中提到的新乘法,解决方案是:

      output = np.einsum('ij,ik->kij',vals,factors)
      

      这会将 vals 中的 [i,j] 乘以因子中的 [i,k] 并将其放在输出中的 [k,i,j] 中。

      输出:

      [[[ 1.  2.  3.]
        [ 8. 10. 12.]
        [21. 24. 27.]]
      
       [[ 4.  8. 12.]
        [20. 25. 30.]
        [42. 48. 54.]]]
      

      【讨论】:

      • Ehsan - 谢谢。我以前从未使用过 einsum - 非常有用!!!!我不确定是将这个答案标记为最佳解决方案还是来自 Quang 的答案,因为两者都给出了我需要的结果并且几乎同时运行。我决定使用这个,因为它只是一个阴影更快,并向我介绍了一项新功能......
      • 我很高兴它有所帮助。 einsum 比这个例子更强大。知道它的力量,你会喜欢使用它。
      【解决方案4】:

      我唯一能理解的输入和输出是如果你将每一行 vals 与所有因子的相应索引相乘,但你需要匹配因子和 vals 的维度。

      import numpy as np
      
      vals=np.array([[1.0, 2.0, 3.0],[4.0, 5.0, 6.0],[7.0, 8.0, 9.0]], np.float32) # shape = mxn
      
      print(vals.shape)
      
      factors=np.array([[1.0, 4.0], [2.0, 5.0], [3.0, 6.0]]) # shape = nxk increasing dim to match with vals.shape
      
      m = vals.shape[0]
      n = vals.shape[1]
      k = factors.shape[1]
      
      print(factors.shape)
      
      
      
      result = np.array([np.array([vals[j]*np.repeat(factors[:,i], n).reshape(n,n) for i in range(k)]) for j in range(m)])
      
      print(result[0])
      
      
      (3, 3)
      (3, 2)
      [[[ 1.  2.  3.]
        [ 2.  4.  6.]
        [ 3.  6.  9.]]
      
       [[ 4.  8. 12.]
        [ 5. 10. 15.]
        [ 6. 12. 18.]]]
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-11-07
        • 1970-01-01
        • 2016-12-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-09-02
        • 1970-01-01
        相关资源
        最近更新 更多