如何有效地将二维数组中的每个元素乘以 Numpy 中的一维数组?

How to efficiently multiply every element in a 2-dimensional array by a 1-dimensional array in Numpy?

我想使用 numpy 高效地将二维数组中的每个元素与一维数组相乘,以便返回 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]]])

非常感谢您!

使用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]]])

作为@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]]])

如果您不习惯该函数的下标输入,它的缺点是不够直观,但值得一试。

(arr1.reshape(arr2.size, 1) * arr2.reshape(1, arr2.size)).reshape(3, 3, 9)