48

n個の正方行列A1、...、Anがあるとします。これらの行列をきちんと乗算する方法はありますか?私の知る限り、numpyのドットは2つの引数しか受け入れません。明らかな方法の1つは、それ自体を呼び出して結果を取得する関数を定義することです。それを成し遂げるためのより良い方法はありますか?

4

5 に答える 5

78

これは比較的最近の機能かもしれませんが、私は次のことを気に入っています。

A.dot(B).dot(C)

または、長いチェーンがある場合は、次のことができます。

reduce(numpy.dot, [A1, A2, ..., An])

アップデート:

reduce hereに関する詳細情報があります。役立つ例を次に示します。

>>> A = [np.random.random((5, 5)) for i in xrange(4)]
>>> product1 = A[0].dot(A[1]).dot(A[2]).dot(A[3])
>>> product2 = reduce(numpy.dot, A)
>>> numpy.all(product1 == product2)
True

2016 年更新: Python 3.5 の時点で、新しい matrix_multiply シンボルがあり@ます。

R = A @ B @ C
于 2012-08-07T05:12:31.673 に答える
42

古い質問を更新して復活させる:

2014 年 11 月 13 日の時点で、np.linalg.multi_dot必要な機能を正確に実行できる関数が追加されました。また、呼び出し順序を最適化するという利点もありますが、あなたの場合は必要ありません。

これは、numpy バ​​ージョン 1.10 以降で使用できることに注意してください。

于 2014-11-18T16:58:32.670 に答える
4

すべての行列を事前に計算する場合は、行列の連鎖乗積の最適化スキームを使用する必要があります。このウィキペディアの記事を参照してください。

于 2012-08-07T02:05:48.733 に答える
4

これを達成する別の方法は、NumPyのアインシュタイン総和規則einsumを実装するを使用することです。

この問題に関してこの規則を非常に簡単に説明すると、次のようになります。複数の行列積を積の 1 つの大きな和として書き出すと、次のようになります。

P_im = sum_j sum_k sum_l A1_ij A2_jk A3_kl A4_lm

ここPで、 は積の結果、A1A2A3、およびA4は入力行列です。加数に 2 回現れるインデックス、つまりjk、およびを正確に合計することに注意してくださいl。このプロパティを持つ合計は、物理学、ベクトル計算、およびおそらく他の分野でよく見られるため、そのための NumPy ツール、つまり がありeinsumます。

上記の例では、次のようにマトリックス積を計算するために使用できます。

P = np.einsum( "ij,jk,kl,lm", A1, A2, A3, A4 )

ここで、最初の引数は関数にどのインデックスを引数行列に適用するかを伝え、次にすべての二重に現れるインデックスが合計され、望ましい結果が得られます。

計算効率はいくつかの要因に依存することに注意してください (したがって、おそらくテストするだけで十分です)。

于 2016-10-03T07:14:18.740 に答える
2
A_list = [np.random.randn(100, 100) for i in xrange(10)]
B = np.eye(A_list[0].shape[0])
for A in A_list:
    B = np.dot(B, A)

C = reduce(np.dot, A_list)

assert(B == C)
于 2012-08-07T08:07:16.857 に答える