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