pythonのnumpyパッケージで操作の中心となるのはndarrayクラスです。ndarrayクラスは1次元配列にも2次元配列にもそれ以上の次元の配列にもなりますが、ここでは2次元配列、つまり行列として利用する場合に焦点を絞って、操作法を練習します。
行列の作成
行列の作成法はいろいろあります。まずは要素を全列挙する方法。以下は2x5の行列を作成したところです。
>>> numpy.array([[1,2,3,4,5], [6,7,8,9,10]]) array([[ 1, 2, 3, 4, 5], [ 6, 7, 8, 9, 10]])
3x4の零行列を作成するにはzeros()です。
>>> numpy.zeros([3,4]) array([[ 0., 0., 0., 0.], [ 0., 0., 0., 0.], [ 0., 0., 0., 0.]])
同様に3x4の、1埋めの行列を作るにはones()を使います。
>>> numpy.ones([3, 4]) array([[ 1., 1., 1., 1.], [ 1., 1., 1., 1.], [ 1., 1., 1., 1.]])
5で埋めたければ*5すればOKです。
>>> numpy.ones([3,4]) * 2 array([[ 2., 2., 2., 2.], [ 2., 2., 2., 2.], [ 2., 2., 2., 2.]])
3x3の単位行列の作成にはidentity()を使います
>>> numpy.identity(3) array([[ 1., 0., 0.], [ 0., 1., 0.], [ 0., 0., 1.]])
非正方行列で、対角成分が1でその他が0の行列を作るにはeye()を使います
>>> numpy.eye(4, 3) array([[ 1., 0., 0.], [ 0., 1., 0.], [ 0., 0., 1.], [ 0., 0., 0.]])
ランダムな数字で行列の要素を埋めることもできます。[0, 1)の一様乱数で2x3の行列を作るにはrandom.rand()を使います。
>>> numpy.random.rand(2,3) array([[ 0.06884044, 0.90537231, 0.43847367], [ 0.91323392, 0.22344938, 0.39933672]])
同様に、[10, 13)の範囲の整数で2x3の行列を作るにはrandom.randint()を使います。
>>> numpy.random.randint(10,13,(2,3)) array([[11, 12, 12], [10, 10, 10]])
乱数系はNumpyによる乱数生成まとめ - Qiitaに詳しく載っています。
長さ12のベクトルを作って、reshape()で3x4の行列に形を変えます
>>> numpy.arange(12).reshape(3,4) array([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11]])
他の行列をクローンコピーします。単にb = aとすると同じオブジェクトを参照してしまうので注意
>>> a = numpy.arange(12).reshape(3,4) >>> b = a.copy() >>> b array([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11]])
行列同士の演算
説明用に行列を2つ生成します。
>>> a = numpy.arange(12).reshape(3,4) >>> a array([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11]]) >>> b = numpy.arange(5, 17).reshape(3,4) >>> b array([[ 5, 6, 7, 8], [ 9, 10, 11, 12], [13, 14, 15, 16]])
a + bは予想通り各要素を足し算します。
>>> a + b array([[ 5, 7, 9, 11], [13, 15, 17, 19], [21, 23, 25, 27]])
a * bとすると、もしかすると予想に反した動きかもしれませんが、各要素の積を取ります。
>>> a * b array([[ 0, 6, 14, 24], [ 36, 50, 66, 84], [104, 126, 150, 176]])
a - b, a / bも同様に、各要素ごとに演算を行います。
行列の積をとるにはdot()を使います。行列aと、行列bの転置b.Tの積をとってみます。
>>> a.dot(b.T) array([[ 44, 68, 92], [148, 236, 324], [252, 404, 556]])
余談ですが、Python 3.5では行列の積を計算する演算子'@'が使えるようになるようです。参考:PEP 465 -- A dedicated infix operator for matrix multiplication
numpyのndarrayを使った行列操作練習帳 その2 - minus9d's diary に続きます。
補足
numpyにはndarrayの他に、行列に特化したクラス(matrixクラス)も用意しているようですが、あまり使われていないようです。参考:python - Matrix and array multiplication in numpy - Stack Overflow