numpy 行列ベクトル乗算 [重複] 質問する

numpy 行列ベクトル乗算 [重複] 質問する

サイズ (nxn)*(nx 1) の2 つの配列を乗算するとnumpy、サイズ (nxn) の行列が得られます。通常の行列乗算ルールに従うと、(nx 1) ベクトルが期待されますが、Python の Numpy モジュールでこれがどのように行われるかについての情報がまったく見つかりません。

問題は、プログラムの速度を維持するために手動で実装したくないということです。

サンプルコードを以下に示します。

a = np.array([[5, 1, 3], [1, 1, 1], [1, 2, 1]])
b = np.array([1, 2, 3])

print a*b
   >>
   [[5 2 9]
   [1 2 3]
   [1 4 3]]

私が欲しいのは:

print a*b
   >>
   [16 6 8]

ベストアンサー1

最も簡単な解決策

numpy.dotまたは を使用してくださいa.dot(b)。ドキュメントを参照してくださいここ

>>> a = np.array([[ 5, 1 ,3], 
                  [ 1, 1 ,1], 
                  [ 1, 2 ,1]])
>>> b = np.array([1, 2, 3])
>>> print a.dot(b)
array([16, 6, 8])

これは、NumPy 配列が行列ではなく、標準操作が*, +, -, /配列の要素ごとに実行されるために発生します。

ただし、numpy.matrix(2021年初頭現在)は*標準の行列乗算のように扱われますが、numpy.matrix非推奨であり、将来のリリースで削除される可能性がありますドキュメント内の注記(以下に転載):

線形代数の場合でも、このクラスを使用することは推奨されません。代わりに通常の配列を使用してください。このクラスは将来削除される可能性があります。

@HopeKing ありがとう。


その他のソリューション

他にも選択肢があることも知っておいてください:

  • 下記のように、python3.5+ および numpy v1.10+ を使用する場合、演算子は@期待どおりに動作します。

    >>> print(a @ b)
    array([16, 6, 8])
    
  • やりすぎたい場合は、numpy.einsumドキュメントを読むと、それがどのように機能するかがわかりますが、正直に言うと、私は読むまで使い方を完全に理解していませんでした。この答えそして、自分で遊んでみました。

    >>> np.einsum('ji,i->j', a, b)
    array([16, 6, 8])
    
  • 2016年半ば(numpy 1.10.1)現在、実験的なnumpy.matmulは、numpy.dot2 つの大きな例外を除いて のように動作します。スカラー乗算はありませんが、行列のスタックでは動作します。

    >>> np.matmul(a, b)
    array([16, 6, 8])
    
  • numpy.inner行列ベクトル乗算と同じように機能しますnumpy.dot が、行列と行列、テンソルの乗算では動作が異なります(違いについてはWikipediaを参照してください)。内積とドット積一般的にまたはこのSOの回答を参照してください(NumPy の実装に関して)

    >>> np.inner(a, b)
    array([16, 6, 8])
    
    # Beware using for matrix-matrix multiplication though!
    >>> b = a.T
    >>> np.dot(a, b)
    array([[35,  9, 10],
           [ 9,  3,  4],
           [10,  4,  6]])
    >>> np.inner(a, b) 
    array([[29, 12, 19],
           [ 7,  4,  5],
           [ 8,  5,  6]])
    
  • 複数の2D配列を組み合わせる場合はdotnp.linalg.multi_dot関数は、多数のネストされた の構文を簡素化しますnp.dot。これは 2D 配列でのみ機能することに注意してください (つまり、行列とベクトルの乗算には機能しません)。

      >>> np.dot(np.dot(a, a.T), a).dot(a.T)
      array([[1406,  382,  446],
             [ 382,  106,  126],
             [ 446,  126,  152]])
      >>> np.linalg.multi_dot((a, a.T, a, a.T))
      array([[1406,  382,  446],
             [ 382,  106,  126],
             [ 446,  126,  152]])
    

エッジケース向けの稀なオプション

  • テンソル(1次元以上の配列)がある場合は、次のように使用できます。numpy.tensordotオプションの引数axes=1:

    >>> np.tensordot(a, b, axes=1)
    array([16,  6,  8])
    
  • 使用しないでくださいnumpy.vdot複素数の行列がある場合、行列は 1D 配列に平坦化されるため、平坦化された行列とベクトル間の複素共役ドット積を見つけようとします (サイズの不一致により失敗しますn*m) n

おすすめ記事