« ^ »

numpyで学ぶ行列

所要時間: 約 2分

ndarray

n次正方行列

shapeの第一要素と第二要素の値が同じになるような行列。

>>> np.array([[1,1], [1,1]])
array([[1, 1],
       [1, 1]])
>>> np.array([[1,1], [1,1]]).shape
(2, 2)
>>> np.array([[1,1,1], [1,1,1], [1,1,1]])
array([[1, 1, 1],
       [1, 1, 1],
       [1, 1, 1]])
>>> np.array([[1,1,1], [1,1,1], [1,1,1]]).shape
(3, 3)
>>> np.array([[1,1,1,1], [1,1,1,1], [1,1,1,1], [1,1,1,1]])
array([[1, 1, 1, 1],
       [1, 1, 1, 1],
       [1, 1, 1, 1],
       [1, 1, 1, 1]])
>>> np.array([[1,1,1,1], [1,1,1,1], [1,1,1,1], [1,1,1,1]]).shape
(4, 4)

ndarrayの属性

階数の取得
obj.ndim
各階の次元数の取得
obj.shape

ndarrayの演算

>>> np.array([[5, 6], [-7, 8]]) + np.array([[1, -2], [3, -4]])
array([[ 6,  4],
       [-4,  4]])

スカラー倍

>>> 5 * np.array([[1, -3, 2], [1, 2, 7]])
array([[  5, -15,  10],
       [  5,  10,  35]])

>>> np.array([[5,6], [-7,8]]) - np.array([[1,-2], [3,-4]])
array([[  4,   8],
       [-10,  12]])

アダマール積

>>> np.array([[5,6], [7,8]]) * np.array([[1,2], [3,4]])
array([[ 5, 12],
       [21, 32]])

内積

>>> np.array([[5,6], [7,8]]) @ np.array([[1,2], [3,4]])
array([[23, 34],
       [31, 46]])

テンソル積 (外積)

>>> np.cross(np.array([[5,6], [7,8]]), np.array([[1,2], [3,4]]))
array([4, 4])

numpyの使い方

3 * 4の行列を作る

numpy.zerosは必要は領域はわかっているけど、生成時に値はわからないためとりえあえず値をpaddingしておく場合に使う。

>>> np.zeros((3,4))
array([[ 0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.]])

ベクトルの生成

1以上10未満の2つ飛ばしの数列で構成されたベクトルを生成する。

>>> np.arange(1, 10, 2)
array([1, 3, 5, 7, 9])

numpy.arange()はrange()と引数が同じ。

テンソルの次元変換

他の次元のテンソルに展開する場合は `numpy.ndarray.reshape()` を使う。第一引数から変換したい各階層の要素数を指定する。

>>> target = np.arange(4)
>>> target
array([0, 1, 2, 3])

このtargetはshapeが(4,)でndimは1である。これを(2,2)の正方行列に展開する。

>>> target.reshape(2,2)
array([[0, 1],
       [2, 3]])

展開前のテンソルのshapeと指定した変換後のshapeが食い違う場合、ValueErrorが早出される。例えば上記でtargetは要素数が4なので平方行列にするには(2,2)になる。これを(2,3)のような行列にはできない。なぜなら(2,3)の行列はスカラーの数が6個必要である。 しかし、targetの要素数は4つしかないため不足してしまう。そのため展開できない。

>>> target.reshape(2,3)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: total size of new array must be unchanged

指定したshapeが小さすぎて要素があまるようなケースも当然展開できない。あまった要素をどうすればいいかがわからないからだ。

>>> np.arange(12).reshape(2,2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: total size of new array must be unchanged

総和/最大/最小は次のように取得できる。

>>> np.array([1,2,3]).sum()
6
>>> np.array([1,2,3]).max()
3
>>> np.array([1,2,3]).min()
1

次の行列を考える。

>>> target = np.arange(12).reshape(3,4)
>>> target
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])

この行列targetに対して行ごともしくは列ごとに演算することもできる。

各列の総和

>>> target.sum(axis=0)
array([12, 15, 18, 21])

各行の最小値

>>> target.min(axis=1)
array([0, 4, 8])

各行の累積和

>>> target.cumsum(axis=1)
array([[ 0,  1,  3,  6],
       [ 4,  9, 15, 22],
       [ 8, 17, 27, 38]])

ベクトルにもどす