5

行列と列ベクトルの内積を計算したいとします。

行列ドット ベクトル

したがって、Numpy/Python では次のようになります。

a=numpy.asarray([[1,2,3], [4,5,6], [7,8,9]])
b=numpy.asarray([[2],[1],[3]])
a.dot(b)

結果:

配列([[13]、[31]、[49]])

これまでのところ、非常にうまくいっていますが、なぜこれも機能しているのでしょうか?

b=numpy.asarray([2,1,3])
a.dot(b)

結果:

配列([13, 31, 49])

[2,1,3] は行ベクトル (ドット積を適用するには転置が必要) であると予想しますが、Numpy はデフォルトで配列を列ベクトルとして認識しているようです (行列乗算の場合)?

これはどのように作動しますか?

編集:

そして、その理由は次のとおりです。

b=numpy.asarray([2,1,3])
b.transpose()==b

そのため、マトリックス ドット ベクトル配列は機能します (そのため、列ベクトルとして認識されます) が、他の操作 (転置) は機能しません。これは本当に一貫したデザインではありませんね。

4

1 に答える 1

5

dotまず、操作が numpy でどのように定義されているかを理解しましょう。

(簡単にするために、ブロードキャスト ルールを議論から除外します) dot(A,B)A の最後の次元 (つまりA.shape[-1]) が B の最後から 2 番目の次元 (つまり B.shape[-2]) と同じ場合に実行できます。 ndim>=2 であり、B.ndim==1 の場合は単純に B の次元です。

言い換えれば、 ifA.shape=(N1,...,Nk,X)B.shape=(M1,...,M(j-1),X,Mj)(一般的な に注意してくださいX)。結果の配列には形状があります(N1,...,Nk,M1,...,Mj)(削除されたことに注意してくださいX)。

または、A.shape=(N1,...,Nk,X)およびの場合B.shape=(X,)。結果の配列には形状があります(N1,...,Nk)(削除されたことに注意してくださいX)。

あなたの例は、ルールを満たしているため機能します(最初の例は最初のものを満たし、2番目は2番目のものを満たします):

a=numpy.asarray([[1,2,3], [4,5,6], [7,8,9]])
b=numpy.asarray([[2],[1],[3]])
a.shape, b.shape, '->', a.dot(b).shape  # X=3
=> ((3, 3), (3, 1), '->', (3, 1))

b=numpy.asarray([2,1,3])
a.shape, b.shape, '->', a.dot(b).shape  # X=3
=> ((3, 3), (3,), '->', (3,))

私の推奨事項は、numpy を使用するときは、「行/列ベクトル」の観点から考えず、可能であれば「ベクトル」の観点からまったく考えず、「形状 S の配列」の観点から考えることです。 . これは、行ベクトルと列ベクトルの両方が単に「1次元配列」であることを意味します。numpy に関する限り、それらはまったく同じです。

これにより、あなたの場合の理由も明確になりますb.transponse() is the same as b転置bされた場合、1次元配列であることは、1次元配列のままです。転置は 1dim 配列には影響しません。

于 2016-01-05T08:59:33.197 に答える