Точечный продукт массива Numpy

Все мы знаем, что скалярное произведение между векторами должно возвращать скаляр:

import numpy as np
a = np.array([1,2,3])
b = np.array([3,4,5])
print(a.shape) # (3,)
print(b.shape) # (3,)
a.dot(b) # 26
b.dot(a) # 26

идеально. НО ПОЧЕМУ, если мы используем «настоящий» (см. Разница между numpy.array shape (R, 1) и (R,)) вектором-строкой или вектором-столбцом, точечный продукт numpy возвращает ошибку по измерению?

arow = np.array([[1,2,3]])
brow = np.array([[3,4,5]])
print(arow.shape) # (1,3)
print(brow.shape) # (1,3)
arow.dot(brow) # ERROR
brow.dot(arow) # ERROR

acol = np.array([[1,2,3]]).reshape(3,1)
bcol = np.array([[3,4,5]]).reshape(3,1)
print(acol.shape) # (3,1)
print(bcol.shape) # (3,1)
acol.dot(bcol) # ERROR
bcol.dot(acol) # ERROR

person arj    schedule 04.01.2019    source источник
comment
Вы забыли опубликовать (или прочитать?) Все сообщение об ошибке. Он сообщает вам, какие измерения пытается согласовать. dot, несмотря на название, является матричным продуктом. Документы поясняют, что обработка 1d-массивов - это особый случай.   -  person hpaulj    schedule 04.01.2019
comment
Если a и b не равны 1d, dot это: произведение суммы по последней оси a и предпоследней оси b. (3,1) может работать с (1,3), но не с (3,1).   -  person hpaulj    schedule 05.01.2019


Ответы (2)


Потому что, явно добавляя второе измерение, вы больше работаете не с векторами, а с двумерными матрицами. При скалярном произведении матриц внутренние размеры изделия должны совпадать.

Поэтому вам необходимо транспонировать одну из ваших матриц. Какой из них вы транспонируете, определит значение и форму результата.

Матрица 1x3, умноженная на 3x1, даст матрицу 1x1 (то есть скаляр). Это внутренний продукт. Матрица 3x1 умноженная на 1x3 даст внешний продукт 3x3.

person Mad Physicist    schedule 04.01.2019
comment
Затем ответьте на stackoverflow.com/questions/22053050/ следует проверить? - person arj; 04.01.2019
comment
@arj. Этот ответ определенно очень хорош, но не полностью соответствует вашему вопросу. Это поможет вам понять, что трехэлементный массив всегда будет одним и тем же в памяти, независимо от того, какую форму или количество измерений вы ему зададите. Это также должно помочь вам понять, как работают размеры матрицы для умножения. - person Mad Physicist; 04.01.2019
comment
Ваш внутренний 1x1 выполняет математику как ваш внешний 3x3, 'ij, jk- ›ik` в einsum нотации. Размер j равен 3 в одном случае и 1 в другом. - person hpaulj; 04.01.2019

Вы также можете использовать оператор @, который на самом деле представляет собой матричное умножение. В этом случае, как и в скалярном произведении, вам нужно знать размеры матриц (ndarray всегда должен быть совместим с тусклым светом), но это более читабельно:

>>> a = np.array([1,2,3])
>>> a.shape
(3,)
>>> b= np.array([[1,2,3]])
>>> b.shape
(1, 3)
>>> a@b
Traceback (most recent call last):
  File "<input>", line 1, in <module>
ValueError: shapes (3,) and (1,3) not aligned: 3 (dim 0) != 1 (dim 0)
>>> [email protected]
array([14])
person YoniChechik    schedule 04.01.2019