numpy
numpy.dot
Szukaj…
Składnia
- numpy.dot (a, b, out = Brak)
Parametry
Nazwa | Detale |
---|---|
za | tablica liczb liczbowych |
b | tablica liczb liczbowych |
na zewnątrz | tablica liczb liczbowych |
Uwagi
numpy.dot
Zwraca iloczyn punktowy aib. Jeśli oba a i b są zarówno skalarami, jak i obydwoma tablicami 1-D, wówczas zwracany jest skalar; w przeciwnym razie zwracana jest tablica. Jeśli podano, to jest zwracane.
Mnożenie macierzy
Mnożenie macierzy można wykonać na dwa równoważne sposoby z funkcją kropki. Jednym ze sposobów jest użycie funkcji członka kropki z 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.]])
Drugim sposobem mnożenia macierzy jest funkcja biblioteki numpy.
>>> np.dot(A,B)
array([[ 4., 4.],
[ 4., 4.],
[ 4., 4.],
[ 4., 4.]])
Produkty kropki wektorowe
Funkcja kropki może być również używana do obliczania iloczynu wektorowego kropek między dwoma jednowymiarowymi tablicami liczbowymi.
>>> v = np.array([1,2])
>>> w = np.array([1,2])
>>> v.dot(w)
5
>>> np.dot(w,v)
5
>>> np.dot(v,w)
5
Parametr wyjściowy
Funkcja kropki numpy ma opcjonalny parametr out = Brak. Ten parametr pozwala określić tablicę, w której ma zostać zapisany wynik. Ta tablica musi mieć dokładnie taki sam kształt i typ jak tablica, która zostałaby zwrócona, w przeciwnym razie zostanie zgłoszony wyjątek.
>>> 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.]])
Spróbujmy zmienić typ wyniku na 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)
A jeśli spróbujemy użyć innej podstawowej kolejności pamięci, powiedzmy w stylu Fortrana (więc kolumny są ciągłe zamiast wierszy), pojawia się również błąd.
>>> 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)
Operacje macierzowe na tablicach wektorów
numpy.dot może być użyty do pomnożenia listy wektorów przez macierz, ale orientacja wektorów musi być pionowa, aby lista ośmiu wektorów dwuskładnikowych wyglądała jak dwa wektory ośmioskładnikowe:
>>> 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.]])
Jeśli lista wektorów jest ułożona odwrotnie (co często ma miejsce), wówczas tablica musi zostać transponowana przed operacją kropkową, a następnie po niej:
>>> 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.]])
Chociaż funkcja kropki jest bardzo szybka, czasem lepiej jest użyć einsum. Odpowiednikiem powyższego byłoby:
>>> np.einsum('...ij,...j', a, b)
Co jest nieco wolniejsze, ale pozwala na pomnożenie listy wierzchołków przez odpowiednią listę macierzy. Byłby to bardzo skomplikowany proces wykorzystujący kropkę:
>>> 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 może być użyty do znalezienia iloczynu kropkowego każdego wektora na liście z odpowiadającym wektorem na innej liście, jest to dość niechlujne i wolne w porównaniu z mnożeniem elementarnym i sumowaniem wzdłuż ostatniej osi. Coś takiego (co wymaga obliczenia znacznie większej tablicy, ale w większości ignorowane)
>>> np.diag(np.dot(b,b.T))
array([ 82., 104., 130., 160., 194., 232., 274., 320.])
Produkt kropkowy za pomocą mnożenia i sumowania elementarnego
>>> (b * b).sum(axis=-1)
array([ 82., 104., 130., 160., 194., 232., 274., 320.])
Korzystanie z einsum można osiągnąć za pomocą
>>> np.einsum('...j,...j', b, b)
array([ 82., 104., 130., 160., 194., 232., 274., 320.])