2016-12-16 10 views
2

私は行列Asとベクトルbsの束を持っていると言います。私は(BS、として)np.innerを行うとどのようにPythonで別のペアごとに行列のベクトル内積を行うには?

As = array([[[1, 7], [3, 8]], 
      [[2, 1], [5, 9]], 
      [[7, 2], [8, 3]]]) 
bs = array([[8, 0], [8, 8], [7, 3]]) 

、私が取得:

array([[[ 8, 64, 28], [ 24, 88, 45]], 
     [[ 16, 24, 17], [ 40, 112, 62]], 
     [[ 56, 72, 55], [ 64, 88, 65]]]) 

しかし、私はすべての内積を必要としません。私が望むのは、各ベクトルを使って各行列を一度計算することです。そして、私が期待される行列を得る

np.array(map(lambda (a, b): np.inner(a, b), zip(As, bs))) 

array([[ 8, 24], [ 24, 112], [ 55, 65]]) 

私は> 10この操作を必要とするので、今、私はなどをマッピング、郵便番号を使用しない** 私はこのような何かを行うことができます6時間(画像処理用、GMM用)。 numpy、scipyなどを使ってこれを行う方法はありますか?あなたがnp.einsum使用することができます

答えて

2

(速いとefficent) - np.array(map(lambda (a, b): np.inner(a, b), zip(As, bs)))

np.einsum('ijk,ik->ij',As, bs) 

説明

を、我々はaとしてAsオフ最初の要素を選択し、bsオフbとして内積を行っています。したがって、我々がやっている:ループとしてその

In [19]: np.inner(As[0],bs[0]) 
Out[19]: array([ 8, 24]) 

In [20]: np.inner(As[1],bs[1]) 
Out[20]: array([ 24, 112]) 

In [21]: np.inner(As[2],bs[2]) 
Out[21]: array([55, 65]) 

思うが、我々はbsと同じであるAsの最初の軸の長さに対応し、3回の反復します。したがって、lambdaの式を見ると、各繰り返しで、a = As[0] & b = bs[0],a = As[1] & b = bs[1]などとなります。

Asbs3D2Dされ、私たちの心に内積を想像イテレータとしてそれらを表現しましょう。したがって、繰り返し時には、a : j,kb : mとなります。 abの間の内積を使用すると、aの2番目の軸を失い、最初はbになります。したがって、kmに揃える必要があります。したがって、bkと同じイテレータを持つと仮定できます。 aからAsb~bsを参照すると、本質的には、Asから3番目の軸を失い、bsから2番目の軸を内積/総和で失います。 Asbsの最初の軸に沿って反復することは、これらの和の下でそれらを整列させておく必要があることを示しています。

まとめましょう。

  • bsの最初に位置合わせAsの第一の軸を保持:意図操作に関与

    As : i x j x k 
    bs : i x k 
    

    ステップ -

    我々はそうのような入力アレイの関与イテレータを有します。

  • Asの第3軸を失い、bsの秒に対する合計を減らします。

したがって、出力のためにイテレータi,jが残っています。

np.einsumは、非常に効率的な実装であり、入力配列の軸の1つ以上をお互いに整列させる必要がある場合に特に便利です。

einsumの詳細については、先に提供されたドキュメントリンクに従うことをお勧めします。this Q&Aも役立ちます。

+0

これは正確には何ですか?私は本当にそのeinsumを理解していません... – PiMathCLanguage

+1

@PiMathCLanguageいくつかのコメントを追加しました。それらをチェックしてください。 – Divakar

関連する問題