In [265]: A = np.array([[1,1,1],[2,2,2]])
...: B = np.array([[3,3,3], [4,4,4]])
Элементное умножение с последующим суммированием отлично работает:
In [266]: np.sum(A*B, axis=1)
Out[266]: array([ 9, 24])
einsum
также упрощает выражение:
In [267]: np.einsum('ij,ij->i',A,B)
Out[267]: array([ 9, 24])
dot
с 2d массивами (здесь (2,3) shape), выполняет матричное умножение, classi c по строкам, по столбцам вниз. В обозначении einsum
это 'ij, jk-> ik'.
In [268]: np.dot(A,B)
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-268-189f80e2c351> in <module>
----> 1 np.dot(A,B)
<__array_function__ internals> in dot(*args, **kwargs)
ValueError: shapes (2,3) and (2,3) not aligned: 3 (dim 1) != 2 (dim 0)
При транспонировании размеры совпадают (2,3) с (3,2), но результат (2, 2):
In [269]: np.dot(A,B.T)
Out[269]:
array([[ 9, 12],
[18, 24]])
Желаемые значения указаны по диагонали.
Один из способов подумать о проблеме - это то, что мы хотим сделать партию продуктов 1d. matmul/@
был добавлен для выполнения пакетного умножения матриц (чего не может dot
). Но массивы должны быть расширены до 3d, поэтому размер пакета является ведущим (и 3 находятся в соответствующем последнем и от второго до последнего измерения):
In [270]: A[:,None,:]@B[:,:,None] # (2,1,3) with (2,3,1)
Out[270]:
array([[[ 9]],
[[24]]])
Но результат (2 , 1,1) фасонный. Правильные числа есть, но нам нужно выжать дополнительные измерения.
В целом, тогда первые 2 решения самые простые - сумма или произведение или einsum
эквивалент.