numpy
numpy.dot
サーチ…
構文
- numpy.dot(a、b、out = None)
パラメーター
名 | 詳細 |
---|---|
a | 数の少ない配列 |
b | 数の少ない配列 |
でる | 数の少ない配列 |
備考
numpy.dot
aとbの内積を返します。 aとbが共にスカラーまたは両方の1次元配列である場合、スカラーが返されます。それ以外の場合は配列が返されます。 outが与えられた場合、それが返されます。
行列乗算
行列乗算は、ドット関数で2つの等価な方法で行うことができます。 1つの方法は、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.]])
行列の乗算を行う2番目の方法はnumpyライブラリ関数です。
>>> np.dot(A,B)
array([[ 4., 4.],
[ 4., 4.],
[ 4., 4.],
[ 4., 4.]])
ベクトルドット製品
ドット関数は、2つの1次元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ドット関数には、オプションのパラメータ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は、ベクトルのリストに行列を掛けるために使用できますが、ベクトルの向きは、8つの2つの成分ベクトルのリストが2つの8つの成分ベクトルのように見えるように、垂直でなければなりません。
>>> 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.]])
ドット機能は非常に高速ですが、エインサムを使用する方が良い場合もあります。上記と同等のものは次のようになります:
>>> 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.])
エインサムを使用することは、
>>> np.einsum('...j,...j', b, b)
array([ 82., 104., 130., 160., 194., 232., 274., 320.])