White scenery @showyou, hatena

If you have any comments, you may also send twitter @shsub or @showyou.

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列)として定義する

  • +、*、@を使う