Вычислить точечное произведение массива массивов nxn с массивами nx1 - PullRequest
0 голосов
/ 27 февраля 2019

Учитывая:

A = np.array([[[10, -1],
               [-1, 10]],
              [[30,  4],
               [5,  10]]])
B = np.array([[[5],[2]],
              [[3],[4]]])

Я хотел бы взять скалярное произведение между двумя массивами с массивами 2x2 в A и массивами 2x1 в B, поэтому я хотел бы сделать следующее:

res = dot(A, B)

Такой, что результат будет:

res = [[[48],[15]],[[106],[55]]]

Или, возможно, проще:

res = [[48, 15], [106, 55]]

Но я знаю, что мой массив A довольно длинный, так чтоA.shape равно mx2x2, а мой массив B всегда имеет длину, равную, то есть B.shape равно mx2x1. m может быть любым значением, например 250, 000.

Я попытался np.tensordot, но не смог понять, как правильно настроить оси для работы, чтобы получить результат, которого я добился.Как мне выполнить это точечное произведение вложенных массивов?

Ответы [ 2 ]

0 голосов
/ 27 февраля 2019
In [60]: A = np.array([[[10, -1], 
    ...:                [-1, 10]], 
    ...:               [[30,  4], 
    ...:                [5,  10]]]) 
    ...: B = np.array([[[5],[2]], 
    ...:               [[3],[4]]])                                              
In [61]: A                                                                      
Out[61]: 
array([[[10, -1],
        [-1, 10]],

       [[30,  4],
        [ 5, 10]]])
In [62]: A.shape                                                                
Out[62]: (2, 2, 2)
In [63]: B.shape                                                                
Out[63]: (2, 2, 1)

matmul, @ предназначен для выполнения dot для «партий» следующим образом:

In [64]: A@B                                                                    
Out[64]: 
array([[[ 48],
        [ 15]],

       [[106],
        [ 55]]])

einsum также работает

In [65]: np.einsum('mij,mjl->mil',A,B)                                          
Out[65]: 
array([[[ 48],
        [ 15]],

       [[106],
        [ 55]]])

np.dot выполняет внешнее произведение по измерениям, которые не суммируются:

In [66]: np.dot(A,B).shape                                                      
Out[66]: (2, 2, 2, 1)

Ваш желаемый результат может быть извлечен из диагонали, но это медленнее, поскольку он фактически отбрасывает половинурезультаты:

In [68]: np.dot(A,B)[range(2),:,range(2),:]                                     
Out[68]: 
array([[[ 48],
        [ 15]],

       [[106],
        [ 55]]])
0 голосов
/ 27 февраля 2019

Матричное умножение можно выполнять двумя способами: numpy:

1) Точечное произведение двух массивов

np.dot(A,B)

вывод:

array([[[[ 48],
         [ 26]],

        [[ 15],
         [ 37]]],


       [[[158],
         [106]],

        [[ 45],
         [ 55]]]])

2) Умножение по элементам (произведение Адамара):

np.multiply(A,B)

, вывод:

array([[[50, -5],
        [-2, 20]],

       [[90, 12],
        [20, 40]]])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...