Numpyのndarrayとmatrixでは*の結果が異なる
(この記事はQiitaからの転載になります。)
すごい初歩的な話なんですが・・
In [1]: import numpy as np In [2]: H = np.matrix([[1, 2], [3, 4]]) In [3]: H * H Out[3]: matrix([[ 7, 10], [15, 22]]) In [4]: J = np.array([[1, 2], [3, 4]]) In [5]: J * J Out[5]: array([[ 1, 4], [ 9, 16]])
という感じに、np.matrixの*は行列の掛け算であるのに対し、np.arrayは要素毎の積(アダマール積)になってるんですね。np.arrayの方もnp.dotを使えば行列の掛け算になります。
In [6]: np.dot(J, J) Out[6]: array([[ 7, 10], [15, 22]])
np.powerっていう関数もあるんですが、これは単に要素毎のべき乗を取ってるようで、
In [8]: np.power(J, 2) Out[8]: array([[ 1, 4], [ 9, 16]]) In [9]: np.power(H, 2) Out[9]: matrix([[ 1, 4], [ 9, 16]])
とどちらも同じ結果になるのですが、行列のべき乗は関数ないんでしょうか? x >= 1 なら、
def matpow(A, x): B = A for _ in range(x - 1): B = np.dot(B, A) return B
In [14]: matpow(J, 2) Out[14]: array([[ 7, 10], [15, 22]])
で行ける感じもするんですが、ndarray用に作ってるのにmatとか付けるのがイケてなかったり、0乗や逆行列はどうすんだって問題もあります。
ちなみに ** 演算子はnp.matrixではnp.powerと違う挙動をします。
In [13]: H ** 2 Out[13]: matrix([[ 7, 10], [15, 22]])
皆さんどうしてるんでしょうか?
これに対するコメント
numpy.matrixは使わない
ベクトルも明示的に行列(1行n列、もしくは、n行1列)として定義する
+、*、@を使う