web-dev-qa-db-ja.com

行列乗算演算子@をnumpyのスカラーに対して機能させる

python 3.5では、 PEP465 に続いて、行列の乗算に_@_演算子が導入されました。これは、たとえばnumpyで matmul演算子として実装されます。

ただし、PEPによって提案されているように、numpy演算子は、スカラーオペランドで呼び出されると例外をスローします。

_>>> import numpy as np
>>> np.array([[1,2],[3,4]]) @ np.array([[1,2],[3,4]])    # works
array([[ 7, 10],
       [15, 22]])
>>> 1 @ 2                                                # doesn't work
Traceback (most recent call last):
  File "<input>", line 1, in <module>
TypeError: unsupported operand type(s) for @: 'int' and 'int'
_

スカラーと行列の両方で機能する数値信号処理アルゴリズムを実装しているので、これは私にとって本当のターンオフです。 「1-Dx1-D行列の乗算」はスカラー倍算と同等であるため、両方の場合の方程式は数学的に正確に同等です。これは当然のことです。ただし、現在の状態では、両方のケースを正しく処理するために、重複したコードを作成する必要があります。

それで、現在の状態が満足のいくものではないことを考えると、_@_演算子をスカラーに対して機能させることができる合理的な方法はありますか?カスタムの__matmul__(self, other)メソッドをスカラーデータ型に追加することを考えましたが、関連する内部データ型の数を考えると、これは非常に面倒なようです。 numpy配列データ型の___matmul___メソッドの実装を変更して、1x1配列オペランドの例外をスローしないようにできますか?

そして、補足として、この設計決定の背後にある理論的根拠はどれですか?頭から離れて、スカラーにもその演算子を実装しないという説得力のある理由は考えられません。

8
jhin

ajcr が示唆しているように、乗算されるオブジェクトに最小限の次元を強制することで、この問題を回避できます。 2つの合理的なオプションがあります: atleast_1datleast_2d _@_によって返される型に関して異なる結果があります:スカラーと1行1列2Dアレイ。

_x = 3
y = 5
z = np.atleast_1d(x) @ np.atleast_1d(y)   # returns 15 
z = np.atleast_2d(x) @ np.atleast_2d(y)   # returns array([[15]])
_

しかしながら:

  • Atleast_2dを使用すると、xとyが1D配列の場合にエラーが発生します。そうでない場合は、通常どおりに乗算されます。
  • Atleast_1dを使用すると、結果はスカラーまたは行列のいずれかになり、どちらかがわかりません。
  • これらは両方とも、これらすべてのケースを処理するnp.dot(x, y)よりも冗長です。

また、少なくとも_1dバージョンには、スカラー@スカラー=スカラーを使用することで共有されるのと同じ欠陥があります。出力で何ができるかわかりません。 _z.T_または_z.shape_はエラーをスローしますか?これらは1行1列の行列では機能しますが、スカラーでは機能しません。 Pythonの設定では、スカラーと1行1列の配列の違いを無視することはできず、後者のすべてのメソッドとプロパティを放棄する必要があります。

1
user6655984