Numpy逆引きメモ

  • Numpyでよく使う操作のメモ。自分用、随時追記

生成

リストで指定した内容の行列を生成

>>> x = np.array([[0,1],[3,4]])
>>> x
array([[0, 1],
       [3, 4]])

numpy行列からlistへの変換

>>> x = np.array([3,4,5])
>>> x
array([3, 4, 5])
>>> list(x)
[3, 4, 5]

2次元配列で同じことをすると

>>> x
array([[0, 1],
       [3, 4]])
>>>
>>> list(x)
[array([0, 1]), array([3, 4])]

となる。もし多重リスト形式に変換したければ、

>>> x = np.array([[0,1],[3,4]])
>>> x.tolist()
[[0, 1], [3, 4]]
>>> x_list = x.tolist()
>>> x_list
[[0, 1], [3, 4]]

1で埋めた行列を生成

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

0で埋めた行列を生成

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

対角行列の生成

>>> np.eye(4)
array([[ 1.,  0.,  0.,  0.],
       [ 0.,  1.,  0.,  0.],
       [ 0.,  0.,  1.,  0.],
       [ 0.,  0.,  0.,  1.]])

必ず正方行列になる。

ランダム要素で埋めた行列を生成

一様分布

np.random.uniform(2, -3, (5, 4))

上記の意味: 2から-3の間の値で埋めた5, 4の行列を生成する (4つの値が入ったリストが5つ入っているリスト)

指定区間の数列を生成する

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

Stepや始点・終点も指定可

>>> X = np.arange(8,20,2)
>>> X
array([ 8, 10, 12, 14, 16, 18])

指定数がStepの倍数でない場合

>>> X = np.arange(70,40,-11)
>>> X
array([70, 59, 48])

型指定も可

>>> X = np.arange(10.,dtype=np.float32)
>>> X
array([ 0.,  1.,  2.,  3.,  4.,  5.,  6.,  7.,  8.,  9.], dtype=float32)

情報取得

行列の要素数を取得する

>>> h = np.array([2,3,4])
>>> h.size
3
>>> h = np.array([[1,2,3],[4,5,6]])
>>> h.size
6

行列の形状を取得する

>>> h = np.array([[1,2,3],[4,5,6]])
>>> h.shape
(2, 3)

行列の次元数を取得する

>>> h = np.array([[1,2,3],[4,5,6]])
>>> h.ndim
2

行列のrankを取得する

>>> A
array([[1, 2],
       [3, 4]])
>>> np.linalg.matrix_rank(A)
2

形の一致する二つの行列で値が一致する数をカウントする

>>> y=np.array([1,1,2,3,7])
>>> t=np.array([1,2,3,4,7])
>>>
>>> np.sum(y==t)
2

行列から最大値を抽出する

>>> hoge = np.array([[3,4,5],[2,3,4]])
>>> hoge.__class__
<class 'numpy.ndarray'>
>>> np.max(hoge)
5

行列から最大値のindexを取り出す

>>> hoge = np.ndarray([[3,4,5],[2,3,4]])
>>> np.argmax(hoge)
2

軸を指定してsumの最大値を取り出す

>>> A = np.array([[3,4,5],[2,3,4]])
>>> np.max(A, axis=0)
array([3, 4, 5])
>>> np.max(A, axis=1)
array([5, 4])

特定の条件を満たす要素のindexを取得する

>>> a
array([ 1,  3,  4,  2,  5,  8, 10])
>>> np.where(a>3)
(array([2, 4, 5, 6]),)
>>>
>>> np.where(a==3)
(array([1]),)

形状操作

行列の次元数を追加する

>>> h = np.array([1,2,3])
>>> h
array([1, 2, 3])
>>>
>>> h = h[np.newaxis,:]
>>> h
array([[1, 2, 3]])

>>> h = h[:, np.newaxis]
>>> h
array([[1],
       [2],
       [3]])

行列を結合する(連結する)

>>> A
array([[1, 2],
       [3, 4]])
>>> B
array([5, 6])

のとき、

縦に連結

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

横に連結

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

Flattenする

>>> a = np.array([[1,2], [3,4]])
>>> a.flatten()
array([1, 2, 3, 4])

行列を切り落とす(y軸)

>>> h
array([[1, 2, 3],
       [3, 4, 5],
       [4, 5, 6]])
>>> h[1:]
array([[3, 4, 5],
       [4, 5, 6]])
>>> h[:1]
array([[1, 2, 3]])

行列を切り落とす(x軸)

>>> h
array([[1, 2, 3],
       [3, 4, 5],
       [4, 5, 6]])

>>> h[:,1:]
array([[2, 3],
       [4, 5],
       [5, 6]])

>>> h[:,:2]
array([[1, 2],
       [3, 4],
       [4, 5]])

軸操作

多重リスト要素の最大値のインデックスをリストで返す

>>> y = [[1,2,3],[5,6,7]]
>>> t = [[0,0,1],[0,1,0]]
>>> np.argmax(y, axis=1)
>>> y = np.argmax(y, axis=1)
>>>y
array([2, 2])
>>> t = np.argmax(t, axis=1)
>>> t
array([2, 1])

多次元行列から特定次元だけ抜き出す

data = [
[1           ,0.4834],
[2           ,0.5526],
[3           ,0.6076],
[4           ,0.5436],
...
[299         ,0.9718],
[300         ,0.97]
]

という2次元行列があるときに、

[1, 2, 3, ... 299, 300]

を抜き出すには

data[: , 0]
[0.4834, 0.5526, 0.6076, ... 0.97]

を抜き出すには

data[:, 1]

とすればよい

他の例:

>>> y
array([[0, 1],
       [2, 3],
       [4, 5]])

に対して、

>>> y[:,0]
array([0, 2, 4])
>>> y[:,1]
array([1, 3, 5])
>>> y[:,-1]
array([1, 3, 5])

(要素数2なので、前から数えて1番目と後ろから数えて-1番目は同じ)

要素の順番を入れ替える

>>> y
array([[0, 1],
       [2, 3],
       [4, 5]])
>>> y[:,::-1]
array([[1, 0],
       [3, 2],
       [5, 4]])

演算

行列の積を求める

>>> X = np.array([[2,3],[3,4]])
>>> Y = np.array([2,2])
>>> X.dot(Y)
array([10, 14])

"*"による演算は、要素同士の掛け算になるため注意。

>>> X = np.array([[2,3],[3,4]])
>>> Y = np.array([2,2])
>>> X*Y
array([[4, 6],
       [6, 8]])

行列要素の和を取る

>>> A
array([[1, 2],
       [3, 4]])
>>> np.sum(A)
10

線形代数的操作

行列を転置する

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

もしくは

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

transposeは、数式に似せて

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

と書くこともできる

多次元行列については、引数を与えなければx,y,z => z,y,xのように逆順になるが、 順番を与えることもできる

>>> x.transpose(0,1,2)
array([[[ 0,  1,  2],
        [ 3,  4,  5]],

       [[ 6,  7,  8],
        [ 9, 10, 11]]])
>>> x.transpose(0,2,1)
array([[[ 0,  3],
        [ 1,  4],
        [ 2,  5]],

       [[ 6,  9],
        [ 7, 10],
        [ 8, 11]]])
>>> x.transpose(2,0,1)
array([[[ 0,  3],
        [ 6,  9]],

       [[ 1,  4],
        [ 7, 10]],

       [[ 2,  5],
        [ 8, 11]]])

行列式を出力する

>>> A
array([[1, 2],
       [3, 4]])
>>> np.linalg.det(A)
-2.0000000000000004
>>> P
array([[2, 3],
       [4, 5]])
>>> np.linalg.det(P)
-2.0

行列のtraceを出力する

>>> A
array([[1, 2],
       [3, 4]])
>>> np.trace(A)
5 

行列の対角要素を抜き出す

>>> A
array([[1, 2],
       [3, 4]])

>>> np.diag(A)
array([1, 4])

np.diag(A)は、Aの対角要素を返す。

対角要素から対角行列を生成する

>>> a
array([ 1.,  2.,  3.])

>>> np.diag(a)
array([[ 1.,  0.,  0.],
       [ 0.,  2.,  0.],
       [ 0.,  0.,  3.]])

ある行列の固有値の対角行列を得る

>>> np.diag(np.linalg.eigvals(A))
array([[-0.37228132,  0.        ],
       [ 0.        ,  5.37228132]])

行列の固有値を求める

>>> A
array([[1, 2],
       [3, 4]])

>>> np.linalg.eigvals(A)
array([-0.37228132,  5.37228132])

行列の固有値固有ベクトルを求める

>>> A
array([[1, 2],
       [3, 4]])

>>> la, P = np.linalg.eig(A)
>>> la
array([-0.37228132,  5.37228132])
>>> P
array([[-0.82456484, -0.41597356],
       [ 0.56576746, -0.90937671]])

laが固有値、Pが固有ベクトル。 la[n]がP[n,:]に対応する。

行列の逆行列を作る

>>> np.linalg.inv(A)
array([[-2. ,  1. ],
       [ 1.5, -0.5]])

行列の対角化を行う

>>> A
array([[ 0, 14,  2],
       [-1,  9, -1],
       [-2,  4,  8]])

のとき、

>>> l, P = np.linalg.eig(A)
>>> l
array([ 4.,  6.,  7.])
>>> P
array([[  9.42809042e-01,  -9.12870929e-01,  -8.94427191e-01],
       [  2.35702260e-01,  -3.65148372e-01,  -4.47213595e-01],
       [  2.35702260e-01,  -1.82574186e-01,   2.25257672e-15]])

lが固有値、Pが固有ベクトルを組み合わせて作った行列。 l[n]がP[n,:]に対応する(nは0,1,2)

固有値を対角行列化する

>>> D = np.diag(l)
>>> D
array([[ 4.,  0.,  0.],
       [ 0.,  6.,  0.],
       [ 0.,  0.,  7.]])

PDP-1がAと一致することを確認

>>> P.dot(np.diag(l)).dot(np.linalg.inv(P))
array([[  9.79179023e-16,   1.40000000e+01,   2.00000000e+00],
       [ -1.00000000e+00,   9.00000000e+00,  -1.00000000e+00],
       [ -2.00000000e+00,   4.00000000e+00,   8.00000000e+00]])

ベクトルの内積を求める

>>> x
array([1, 2, 3])
>>> y
array([3, 1, 0])
>>> x.dot(y)
5

行列のノルムを求める

>>> x
array([1, 2, 3])
>>> np.linalg.norm(x)
3.7416573867739413

ベクトル同士のcos類似度を求める

内積を双方のノルムで割れば良いので

>>> x
array([1, 2, 3])
>>> y
array([3, 1, 0])
>>> x.dot(y) / (np.linalg.norm(x) * np.linalg.norm(y))
0.42257712736425829

その他よく使うイディオム

多次元配列の要素をイテレーションする

配列の要素のインデックスを順番に取得できる

>>> x
array([[0, 1],
       [3, 4]])
>>> it = np.nditer(x, flags=['multi_index'], op_flags=['readwrite'])
>>> it
<numpy.nditer object at 0x10a444c10>
>>>
>>> it.multi_index
(0, 0)
>>> it.iternext()
True
>>> it.multi_index
(0, 1)
>>> it.iternext()
True
>>> it.multi_index
(1, 0)
>>> it.iternext()
True
>>> it.multi_index
(1, 1)
>>> it.iternext()
False

行列要素の型を変換する

>>> A
array([[1, 2],
       [3, 4]])

>>> A.astype("float32")
array([[ 1.,  2.],
       [ 3.,  4.]], dtype=float32)

(わかりづらいが、小数点が付いてfloat型になっている)

map適用相当の関数適用

x = np.array([1, 2, 3, 4, 5])
squarer = lambda t: t ** 2
squares = np.array([squarer(xi) for xi in x])

printしたときに省略せずに表示する

np.set_printoptions(threshold=np.inf)

をコードのどこかで宣言したあとでprint