【问题标题】:How to efficiently multiply every element in a 2-dimensional array by a 1-dimensional array in Numpy?如何有效地将二维数组中的每个元素乘以 Numpy 中的一维数组?
【发布时间】:2020-01-23 12:05:26
【问题描述】:

我想使用 numpy 有效地将 2D 数组中的每个元素与 1D 数组相乘,从而返回 3D 数组。

基本上,代码应该执行以下操作:

import numpy as np

#create dummy data
arr1=np.arange(0,9).reshape((3,3))
arr2=np.arange(0,9)

#create output container
out = []

#loop over every increment in arr1
for col in arr1:

    row = []

    for i in col:

        #perform calculation
        row.append(i*arr2)

    out.append(row)


#convert output to array
out = np.array(out)

没有形状 (3, 3, 9),因此等于

array([[[ 0,  0,  0,  0,  0,  0,  0,  0,  0],
        [ 0,  1,  2,  3,  4,  5,  6,  7,  8],
        [ 0,  2,  4,  6,  8, 10, 12, 14, 16]],

       [[ 0,  3,  6,  9, 12, 15, 18, 21, 24],
        [ 0,  4,  8, 12, 16, 20, 24, 28, 32],
        [ 0,  5, 10, 15, 20, 25, 30, 35, 40]],

       [[ 0,  6, 12, 18, 24, 30, 36, 42, 48],
        [ 0,  7, 14, 21, 28, 35, 42, 49, 56],
        [ 0,  8, 16, 24, 32, 40, 48, 56, 64]]])

非常感谢您!

【问题讨论】:

  • 如果 arr1 的形状为 (3,3,1),您可以简单地使用 arr1*arr2 来生成 (3,3,9)

标签: python numpy elementwise-operations


【解决方案1】:

使用numpy.outer:

np.outer(arr2,arr1).reshape(3,3,9)

得到:

array([[[ 0,  0,  0,  0,  0,  0,  0,  0,  0],
        [ 0,  1,  2,  3,  4,  5,  6,  7,  8],
        [ 0,  2,  4,  6,  8, 10, 12, 14, 16]],

       [[ 0,  3,  6,  9, 12, 15, 18, 21, 24],
        [ 0,  4,  8, 12, 16, 20, 24, 28, 32],
        [ 0,  5, 10, 15, 20, 25, 30, 35, 40]],

       [[ 0,  6, 12, 18, 24, 30, 36, 42, 48],
        [ 0,  7, 14, 21, 28, 35, 42, 49, 56],
        [ 0,  8, 16, 24, 32, 40, 48, 56, 64]]])

【讨论】:

  • 感谢您的回答。不幸的是,这种方法并没有模仿上述嵌套循环的行为。如果您尝试在不同的数组上操作它,您会发现重塑并没有保持所需的层次结构。
【解决方案2】:

除了@makis 的回答中的np.outer 产品,您可以像这样直接使用np.einsum

out_einsum = np.einsum('i,jk->jki', arr2, arr1)

然后避免重塑。因此,也给予:

>>> array([[[ 0,  0,  0,  0,  0,  0,  0,  0,  0],
            [ 0,  1,  2,  3,  4,  5,  6,  7,  8],
            [ 0,  2,  4,  6,  8, 10, 12, 14, 16]],

           [[ 0,  3,  6,  9, 12, 15, 18, 21, 24],
            [ 0,  4,  8, 12, 16, 20, 24, 28, 32],
            [ 0,  5, 10, 15, 20, 25, 30, 35, 40]],

           [[ 0,  6, 12, 18, 24, 30, 36, 42, 48],
            [ 0,  7, 14, 21, 28, 35, 42, 49, 56],
            [ 0,  8, 16, 24, 32, 40, 48, 56, 64]]])

如果您不习惯函数下标输入,这有一个缺点是不太直观,但值得一试。

【讨论】:

  • 太棒了。谢谢!
【解决方案3】:
(arr1.reshape(arr2.size, 1) * arr2.reshape(1, arr2.size)).reshape(3, 3, 9)

【讨论】:

    猜你喜欢
    • 2021-01-17
    • 2016-04-15
    • 2022-07-12
    • 2021-09-23
    • 1970-01-01
    • 2015-07-13
    • 2023-02-03
    • 2016-12-07
    • 2019-05-08
    相关资源
    最近更新 更多