【问题标题】:Divide each dimension with different number from a list in numpy从numpy的列表中用不同的数字划分每个维度
【发布时间】:2020-11-20 15:49:20
【问题描述】:

我有形状为 (3,3,3) 的 ndarray 并列出了 3 个数字。

我想将第一个维度与列表中的第一个数字相除,第二个维度与第二个数字相除,第三个维度与第三个数字相除。

例子:

np.random.rand(3,3,3)

>>>array([[[0.90428811, 0.60637664, 0.45090308],
        [0.17400851, 0.49163535, 0.62370288],
        [0.58701608, 0.91207839, 0.69364496]],

       [[0.85290321, 0.85170489, 0.48792597],
        [0.02602198, 0.91088298, 0.14882673],
        [0.63354821, 0.21764451, 0.30760075]],

       [[0.64833375, 0.13583598, 0.50561519],
        [0.42832468, 0.91146014, 0.41627495],
        [0.71238947, 0.37868578, 0.05874898]]])

还有名单:

lst=[0.215, 0.561,0.724]

我希望输出结果是这样的结果:

[0.90428811/0.215, 0.60637664/0.215, 0.45090308/0.215],
        [0.17400851/0.215, 0.49163535/0.215, 0.62370288/0.215],
        [0.58701608/0.215, 0.91207839/0.215, 0.69364496/0.215]],

[[0.85290321/0.561, 0.85170489/0.561, 0.48792597/0.561],
        [0.02602198/0.561, 0.91088298/0.561, 0.14882673/0.561],
        [0.63354821/0.561, 0.21764451/0.561, 0.30760075/0.561]],

 [[0.64833375/0.724, 0.13583598/0.724, 0.50561519/0.724],
        [0.42832468/0.724, 0.91146014/0.724, 0.41627495/0.724],
        [0.71238947/0.724, 0.37868578/0.724, 0.05874898/0.724]]])

我尝试过这样做(arr 是 ndarray):

nums=np.arange(3)

for n in nums:
    arr[i]=arr[i]/lst[i]

但出现错误:

IndexError: 只有整数、切片 (:)、省略号 (...)、 numpy.newaxis (None) 和整数或布尔数组是有效的索引

【问题讨论】:

  • 你可以通过einsum来做到这一点

标签: python numpy numpy-ndarray


【解决方案1】:

只需执行此操作。 broadcastslst 数组的形状 (3, 1, 1) 很容易与 a 的形状相匹配。

请注意,None 只是 np.newaxis 的别名。

import numpy as np
a = np.random.randn(3,3,3)
lst = np.array([0.215, 0.561,0.724])

a / lst[:, None, None]

【讨论】:

  • 成功了!我不确定我理解的唯一事情是它如何不将所有维度与 lst 中的数字分开,它如何知道将其“应用”在正确的维度上
  • 我在我的回答中附上了 numpy 广播的链接。它基本上实际上复制元素以从(3, 1, 1) 生成形状为(3, 3, 3)lst 数组以执行元素除法。您可以查看链接以通过更多示例了解有关广播如何工作的更多信息。随时要求进一步澄清。
【解决方案2】:

使用索引广播:

a = np.random.rand(3,3,3)
res = a / lst[:, np.newaxis, np.newaxis]

这样做的原因是lst[:, np.newaxis, np.newaxis] 生成了一个形状为 (3, 1, 1) 的数组,并且 numpy 将任何大小为 1 的维度扩展为许多常见操作所需的大小(通过重复元素)。这个过程称为广播。

因此,在我们的示例中,对于除法,lst[:, np.newaxis, np.newaxis] 的结果将扩展为:

[[[0.215, 0.215, 0.215],
  [0.215, 0.215, 0.215],
  [0.215, 0.215, 0.215]],

 [[0.561, 0.561, 0.561],
  [0.561, 0.561, 0.561],
  [0.561, 0.561, 0.561]],

 [[0.724, 0.724, 0.724],
  [0.724, 0.724, 0.724],
  [0.724, 0.724, 0.724]]]

请注意,这种扩展仅在概念上发生,numpy 不会分配更多内存只是为了一遍又一遍地用相同的值填充它。

【讨论】:

    【解决方案3】:

    这不是一个很好看的解决方案(因为lst 声明),但它有效:

    import numpy as np
    
    np.random.rand(3,3,3)
    
    arr = np.array([[[0.90428811, 0.60637664, 0.45090308],
            [0.17400851, 0.49163535, 0.62370288],
            [0.58701608, 0.91207839, 0.69364496]],
    
           [[0.85290321, 0.85170489, 0.48792597],
            [0.02602198, 0.91088298, 0.14882673],
            [0.63354821, 0.21764451, 0.30760075]],
    
           [[0.64833375, 0.13583598, 0.50561519],
            [0.42832468, 0.91146014, 0.41627495],
            [0.71238947, 0.37868578, 0.05874898]]])
            
    lst = [[[0.215]], [[0.561]],[[0.724]]]
    
    div = np.divide(arr, lst)
    
    print(div)
    

    输出将是:

    [[[4.20599121 2.82035647 2.09722363]
      [0.80934191 2.28667605 2.90094363]
      [2.73030735 4.24222507 3.22625563]]
    
     [[1.52032658 1.51819053 0.86974326]
      [0.04638499 1.62367733 0.26528829]
      [1.12931945 0.38795813 0.54830793]]
    
     [[0.8954886  0.18761876 0.69836352]
      [0.59160867 1.25892285 0.5749654 ]
      [0.98396336 0.52304666 0.081145  ]]]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-12-12
      • 2023-03-27
      • 2021-05-02
      • 1970-01-01
      • 1970-01-01
      • 2015-01-29
      相关资源
      最近更新 更多