Как эффективно умножить каждый элемент в 2-мерном массиве на 1-мерный массив в Numpy? - PullRequest
2 голосов
/ 23 января 2020

Я хотел бы эффективно умножить каждый элемент в двумерном массиве на одномерный массив, используя numpy, чтобы возвращался трехмерный массив.

По сути, код должен делать что-то вроде:

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

Большое спасибо заранее!

Ответы [ 3 ]

2 голосов
/ 23 января 2020

Используйте 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]]])
1 голос
/ 23 января 2020

В качестве альтернативы np.outer продукту, как в ответе @makis, вы можете напрямую использовать 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]]])

Недостатком является то, что он немного менее интуитивен, если вы не привыкли к тому, что функция подписывает входные данные, но это стоит попробовать.

0 голосов
/ 23 января 2020
(arr1.reshape(arr2.size, 1) * arr2.reshape(1, arr2.size)).reshape(3, 3, 9)
...