numpy
numpy.dot
Поиск…
Синтаксис
- numpy.dot (a, b, out = None)
параметры
название | подробности |
---|---|
массив numpy | |
б | массив numpy |
из | массив numpy |
замечания
numpy.dot
Возвращает точечный продукт a и b. Если a и b являются скалярами или обоими 1-D массивами, тогда возвращается скаляр; в противном случае массив возвращается. Если дано, то оно возвращается.
Матричное умножение
Матричное умножение может выполняться двумя эквивалентными способами с помощью точечной функции. Один из способов - использовать функцию dot member функции numpy.ndarray.
>>> import numpy as np
>>> A = np.ones((4,4))
>>> A
array([[ 1., 1., 1., 1.],
[ 1., 1., 1., 1.],
[ 1., 1., 1., 1.],
[ 1., 1., 1., 1.]])
>>> B = np.ones((4,2))
>>> B
array([[ 1., 1.],
[ 1., 1.],
[ 1., 1.],
[ 1., 1.]])
>>> A.dot(B)
array([[ 4., 4.],
[ 4., 4.],
[ 4., 4.],
[ 4., 4.]])
Второй способ преобразования матрицы - с помощью функции numpy library.
>>> np.dot(A,B)
array([[ 4., 4.],
[ 4., 4.],
[ 4., 4.],
[ 4., 4.]])
Векторные точечные продукты
Функция точки также может использоваться для вычисления векторных точечных продуктов между двумя одномерными массивами numpy.
>>> v = np.array([1,2])
>>> w = np.array([1,2])
>>> v.dot(w)
5
>>> np.dot(w,v)
5
>>> np.dot(v,w)
5
Параметр out
Функция numpy dot имеет необязательный параметр out = None. Этот параметр позволяет указать массив для записи результата. Этот массив должен быть точно такой же формы и типа, что и массив, который был бы возвращен, или будет выбрано исключение.
>>> I = np.eye(2)
>>> I
array([[ 1., 0.],
[ 0., 1.]])
>>> result = np.zeros((2,2))
>>> result
array([[ 0., 0.],
[ 0., 0.]])
>>> np.dot(I, I, out=result)
array([[ 1., 0.],
[ 0., 1.]])
>>> result
array([[ 1., 0.],
[ 0., 1.]])
Попробуем изменить dtype результата на int.
>>> np.dot(I, I, out=result)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: output array is not acceptable (must have the right type, nr dimensions, and be a C-Array)
И если мы попробуем использовать другой базовый порядок памяти, скажем, стиль Fortran (поэтому столбцы смежны, а не строки), также возникает ошибка.
>>> result = np.zeros((2,2), order='F')
>>> np.dot(I, I, out=result)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: output array is not acceptable (must have the right type, nr dimensions, and be a C-Array)
Матричные операции над массивами векторов
numpy.dot может использоваться для умножения списка векторов на матрицу, но ориентация векторов должна быть вертикальной, так что список из восьми двух компонентных векторов появляется как два восьми вектора компонент:
>>> a
array([[ 1., 2.],
[ 3., 1.]])
>>> b
array([[ 1., 2., 3., 4., 5., 6., 7., 8.],
[ 9., 10., 11., 12., 13., 14., 15., 16.]])
>>> np.dot(a, b)
array([[ 19., 22., 25., 28., 31., 34., 37., 40.],
[ 12., 16., 20., 24., 28., 32., 36., 40.]])
Если список векторов выложен с его осями наоборот (что часто бывает), то массив необходимо перенести до и после операции с точкой, например:
>>> b
array([[ 1., 9.],
[ 2., 10.],
[ 3., 11.],
[ 4., 12.],
[ 5., 13.],
[ 6., 14.],
[ 7., 15.],
[ 8., 16.]])
>>> np.dot(a, b.T).T
array([[ 19., 12.],
[ 22., 16.],
[ 25., 20.],
[ 28., 24.],
[ 31., 28.],
[ 34., 32.],
[ 37., 36.],
[ 40., 40.]])
Хотя функция точки очень быстрая, иногда лучше использовать einsum. Эквивалентом приведенного выше будет:
>>> np.einsum('...ij,...j', a, b)
Это немного медленнее, но позволяет список вершин умножаться на соответствующий список матриц. Это был бы очень запутанный процесс с использованием точки:
>>> a
array([[[ 0, 1],
[ 2, 3]],
[[ 4, 5],
[ 6, 7]],
[[ 8, 9],
[10, 11]],
[[12, 13],
[14, 15]],
[[16, 17],
[18, 19]],
[[20, 21],
[22, 23]],
[[24, 25],
[26, 27]],
[[28, 29],
[30, 31]]])
>>> np.einsum('...ij,...j', a, b)
array([[ 9., 29.],
[ 58., 82.],
[ 123., 151.],
[ 204., 236.],
[ 301., 337.],
[ 414., 454.],
[ 543., 587.],
[ 688., 736.]])
numpy.dot можно использовать для нахождения точечного произведения каждого вектора в списке с соответствующим вектором в другом списке, это довольно грязно и медленно по сравнению с умножением по элементам и суммированием вдоль последней оси. Что-то вроде этого (что требует вычисления гораздо большего массива, но в основном игнорируется)
>>> np.diag(np.dot(b,b.T))
array([ 82., 104., 130., 160., 194., 232., 274., 320.])
Точечный продукт с использованием умножения элементов и суммирования
>>> (b * b).sum(axis=-1)
array([ 82., 104., 130., 160., 194., 232., 274., 320.])
Использование einsum может быть достигнуто с помощью
>>> np.einsum('...j,...j', b, b)
array([ 82., 104., 130., 160., 194., 232., 274., 320.])