Векторное скалярное произведение соответствующих строк с использованием numpy - PullRequest
1 голос
/ 21 июня 2020

Мне нужно вычислить векторное скалярное произведение соответствующих строк двух двумерных массивов u и v в numpy. Строки u являются единичными векторами. Вот пример кода, который иллюстрирует то, что я пытаюсь сделать:

import numpy as np

u = np.array([[1, 0], [.6, .8], [0, 1]])
v = np.array([[1, 2], [3 ,  4], [5, 6]])

Я наивно пытался использовать метод dot numpy, который возвращает следующую ошибку:

np.dot(u, v)
ValueError                                Traceback (most recent call last)
<ipython-input-9-146fe9079c1e> in <module>
----> 1 np.dot(u,v)

<__array_function__ internals> in dot(*args, **kwargs)

ValueError: shapes (3,2) and (3,2) not aligned: 2 (dim 1) != 3 (dim 0)

Несложно определить функцию, которая производит желаемое поведение:

def mydot(a, b):
    return np.sum(a*b,axis=1,keepdims=True)
mydot(u,v)
array([[1.],
[5.],
[6.]])

Однако это кажется немного неуклюжим и оставляет у меня подозрение, что мне не хватает что-то. Есть ли более простой numpy способ сделать это?

Ответы [ 2 ]

0 голосов
/ 21 июня 2020

np.dot действует как матричное умножение при использовании для 2D-массивов, поэтому np.dot(v,u.T) это не даст вам ошибки. Но для скалярного произведения вы можете использовать это:

np.sum(v*u,axis=1)

v*u просто транслируйте 2D-массив, а ось в np.sum() позволяет вам выбрать измерение, в котором вы хотите вычислить скалярное произведение. Надеюсь, ты понял.

0 голосов
/ 21 июня 2020

Ваш способ работает нормально. В то же время вы можете использовать matmul с дополнительным измерением для умножения стеков матриц 1x2 на 2x1:

u[..., None] @ v[:, None, :]

Самая большая разница между matmul и dot заключается в том, что matmul широковещательные передачи исходные размеры, а dot объединяет их.

Но самый быстрый способ, вероятно, einsum:

np.einsum('ij,ij->i', u, v)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...