Умножение матрицы на вектор
Когда я умножаю два числовых массива (n x n)*(n x 1), я получаю матрицу размера (n x n). Следуя нормальным правилам умножения матриц, ожидается вектор (nx 1), но я просто не могу найти никакой информации о том, как это делается в модуле Python Numpy.
Дело в том, что я не хочу реализовывать это вручную, чтобы сохранить скорость работы программы.
Пример кода показан ниже:
a = np.array([[ 5, 1 ,3], [ 1, 1 ,1], [ 1, 2 ,1]])
b = np.array([1, 2, 3])
print a*b
>>
[[5 2 9]
[1 2 3]
[1 4 3]]
Что я хочу это:
print a*b
>>
[16 6 8]
1 ответ
Самое простое решение
использование numpy.dot
или же a.dot(b)
, Смотрите документацию здесь.
>>> a = np.array([[ 5, 1 ,3],
[ 1, 1 ,1],
[ 1, 2 ,1]])
>>> b = np.array([1, 2, 3])
>>> print a.dot(b)
array([16, 6, 8])
Это происходит потому, что массивы numpy не являются матрицами, а стандартными операциями *, +, -, /
работать поэлементно на массивах. Вместо этого вы можете попробовать использовать numpy.matrix
, а также *
будет рассматриваться как матричное умножение.
Другие решения
Также известно, что есть и другие варианты:
Как отмечено ниже, при использовании python3.5+
@
Оператор работает так, как вы ожидаете:>>> print(a @ b) array([16, 6, 8])
Если вы хотите излишнего, вы можете использовать
numpy.einsum
, Документация даст вам представление о том, как это работает, но, честно говоря, я не до конца понимал, как его использовать, пока не прочитал этот ответ и не поиграл с ним самостоятельно.>>> np.einsum('ji,i->j', a, b) array([16, 6, 8])
По состоянию на середину 2016 года (NumPy 1.10.1), вы можете попробовать экспериментальные
numpy.matmul
, который работает какnumpy.dot
с двумя основными исключениями: нет скалярного умножения, но он работает со стеками матриц.>>> np.matmul(a, b) array([16, 6, 8])
numpy.inner
функционирует так же, какnumpy.dot
для умножения матрицы на вектор, но ведет себя по-разному для умножения матрицы на матрицу и тензора (см. Википедию относительно различий между внутренним произведением и точечным произведением в целом или посмотрите этот SO-ответ относительно реализаций numpy).>>> np.inner(a, b) array([16, 6, 8]) # Beware using for matrix-matrix multiplication though! >>> b = a.T >>> np.dot(a, b) array([[35, 9, 10], [ 9, 3, 4], [10, 4, 6]]) >>> np.inner(a, b) array([[29, 12, 19], [ 7, 4, 5], [ 8, 5, 6]])
Редкие варианты для крайних случаев
Если у вас есть тензоры (массивы размерности больше или равны единице), вы можете использовать
numpy.tensordot
с необязательным аргументомaxes=1
:>>> np.tensordot(a, b, axes=1) array([16, 6, 8])
Не использовать
numpy.vdot
если у вас есть матрица комплексных чисел, так как матрица будет сведена к одномерному массиву, то она попытается найти произведение комплексной сопряженной точки между вашей плоской матрицей и вектором (что не удастся из-за несоответствия размераn*m
противn
).