Helve’s Python memo

Pythonを使った機械学習やデータ分析の備忘録

<NumPy> 配列の演算

基本的な四則演算

>>> import numpy as np
>>> a = np.array([[1,2],[3,4]])
>>> b = np.array([[5,6],[7,8]])
>>> a+b             # 足し算
array([[ 6,  8],
       [10, 12]])
>>> b-a             # 引き算
array([[4, 4],
       [4, 4]])
>>> a*b             # 要素ごとの掛け算
array([[ 5, 12],
       [21, 32]])
>>> b/a             # 要素ごとの割り算
array([[ 5.        ,  3.        ],
       [ 2.33333333,  2.        ]])
>>> b%a             # 要素ごとの剰余
array([[0, 0],
       [1, 0]], dtype=int32)
>>> a**2            # 要素ごとの累乗
array([[ 1,  4],
       [ 9, 16]], dtype=int32)

線形代数学の演算

numpy.linalg : 線形代数学(Linear algebra)のライブラリ

内積外積
>>> from numpy import linalg as LA
>>> a = np.array([[1,2],[3,4]])
>>> b = np.array([[5,6],[7,8]])
>>> c = np.array([9, 10])
>>> d = np.array([1, 2, 3])
>>> e = np.array([4, 5, 6])
>>> a.dot(b)              # 行列の内積(その1)
array([[19, 22],
       [43, 50]])
>>> np.dot(a, b)          # 行列の内積(その2)
array([[19, 22],
       [43, 50]])
>>> LA.multi_dot([a,b,c]) # 複数の配列の内積
array([391, 887])
>>> LA.matrix_power(a, 3) # 行列の内積の階乗 (=LA.multi_dot([a,a,a]))
array([[ 37,  54],
       [ 81, 118]])
>>> np.cross(d, e)        # ベクトルの外積
array([-3,  6, -3])
ノルム・行列式・ランク
>>> a = np.array([[1,2],[3,4]])
>>> b = np.array([1,2,3])
>>> LA.norm(b)         # ベクトルのノルム
3.7416573867739413
>>> LA.matrix_rank(a)  # 行列のランク(階数)
2
>>> LA.det(a)          # 行列式 (1*4-2*3)
-2.0000000000000004
転置
>>> a = np.array([[1,2],[3,4]])
>>> a.transpose() # 行列の転置(その1)
array([[1, 3],
       [2, 4]])
>>> a.T           # 行列の転置(その2)
array([[1, 3],
       [2, 4]])
連立方程式の解・逆行列
>>> # 次の連立方程式を解く
>>> # 3x +  y = 9
>>> #  x + 2y = 8
>>> a = np.array([[3,1], [1,2]])
>>> b = np.array([9,8])
>>> LA.solve(a, b)
array([ 2.,  3.])
>>> b = np.array([[1,2],[3,4]])
>>> LA.inv(b)                 # 逆行列
array([[-2. ,  1. ],
       [ 1.5, -0.5]])
固有値固有ベクトル
>>> a = np.array([[1,2],[3,4]])
>>> w, v=LA.eig(a)     # w: 行列の固有値、v: 固有ベクトル(正規化済み)
>>> w
array([-0.37228132,  5.37228132])
>>> v                  # 固有ベクトルv[i]は、固有値w[i]に対応する
array([[-0.82456484, -0.41597356],
       [ 0.56576746, -0.90937671]])
特異値分解
>>> a = np.array([[1, 2, 3], [4, 5, 6]]) # m x n行列のとき
>>> U, s, V = np.linalg.svd(a)           # 特異値分解
>>> U                                    # U: m x mの直行行列
array([[-0.3863177 , -0.92236578],
       [-0.92236578,  0.3863177 ]])
>>> s                                    # s: 特異値
array([ 9.508032  ,  0.77286964])
>>> V                                    # V: n x nの直行行列
array([[-0.42866713, -0.56630692, -0.7039467 ],
       [ 0.80596391,  0.11238241, -0.58119908],
       [ 0.40824829, -0.81649658,  0.40824829]])

参考:
Linear algebra (numpy.linalg) — NumPy v1.13 Manual

広告を非表示にする

<NumPy> 配列の操作

配列のコピー

=でコピーすると、コピー元とコピー先で同じオブジェクトを参照するため、
どちらかを操作するともう片方も変更される (Shallow copy)。
一方、copyメソッドでコピーすると、コピー先で新たにオブジェクトを作成するため、
どちらかを操作しても、もう片方には反映されない (Deep copy)。

>>> import numpy as np
>>> a = np.array([1,2,3])
>>> b=a            # Shallow copy
>>> b[0]=4
>>> b
array([4, 2, 3])
>>> a
array([4, 2, 3])   # aも変更される
>>> c=a.copy()     # Deep copy
>>> c[0]=5
>>> c
array([5, 2, 3])
>>> a
array([4, 2, 3])   # aは変更されない

次元の変更

>>> a = np.array([[1,2,3],
...               [4,5,6]]) # 2x3行列
>>> a.reshape([3,2]) # 3x2行列に変形。ビューを返す。
array([[1, 2],
       [3, 4],
       [5, 6]])
>>> a.reshape([3,-1]) # サイズを指定しない次元を-1とすると、自動的に変形してくれる
array([[1, 2],
       [3, 4],
       [5, 6]])
>>> a.flatten()       # 1次元配列を作成
array([1, 2, 3, 4, 5, 6])

結合

メソッド 記法 説明
vstack np.vstack([a,b]) 縦(0軸)方向に結合
hstack np.hstack([a,b]) 横(1軸)方向に結合
dstack np.dstack([a,b]) 深さ(2軸)方向に結合
concatenate np.concatenate([a,b], axis=0) 指定した軸方向に結合

>>> a = np.array([[0,1],
...               [2,3]])
>>> b = np.array([[4,5],
...               [6,7]])
>>> np.hstack([a,b])
array([[0, 1, 4, 5],
       [2, 3, 6, 7]])
>>> np.vstack([a,b])
array([[0, 1],
       [2, 3],
       [4, 5],
       [6, 7]])
>>> np.concatenate([a,b],axis=0)
array([[0, 1],
       [2, 3],
       [4, 5],
       [6, 7]])
>>> np.concatenate([a,b],axis=1)
array([[0, 1, 4, 5],
       [2, 3, 6, 7]])

分割

メソッド 記法 説明
vsplit np.vsplit(a,n) 縦(0軸)方向に結合・分割
hsplit np.hsplit(a,n) 横(1軸)方向に結合・分割
dsplit np.dsplit(a,n) 深さ(2軸)方向に結合・分割
split np.split(a, axis=0) 指定した軸方向に結合・分割

>>> a=np.arange(16.0).reshape(4, 4)
>>> a
array([[  0.,   1.,   2.,   3.],
       [  4.,   5.,   6.,   7.],
       [  8.,   9.,  10.,  11.],
       [ 12.,  13.,  14.,  15.]])
>>> np.vsplit(a,2)                 # 2つに均等分割
[array([[ 0.,  1.,  2.,  3.],
       [ 4.,  5.,  6.,  7.]]), 
 array([[  8.,   9.,  10.,  11.],
       [ 12.,  13.,  14.,  15.]])]
>>> np.vsplit(a,4)                 # 4つに均等分割
[array([[  0.,   1.,   2.,   3.]]), 
 array([[  4.,   5.,   6.,   7.]]), 
 array([[  8.,   9.,  10.,  11.]]), 
 array([[ 12.,  13.,  14.,  15.]])]
>>> np.vsplit(a,[1,2])             # リストを使うとインデックスで分割
[array([[  0.,   1.,   2.,   3.]]), 
 array([[  4.,   5.,   6.,   7.]]), 
 array([[  8.,   9.,  10.,  11.],
        [ 12.,  13.,  14.,  15.]])]

ソート

>>> a = np.array([1,3,5,2,4])     # 1次元配列の場合
>>> np.sort(a)                    # 昇順にソート
array([1, 2, 3, 4, 5])
>>> np.sort(a)[::-1]              # 降順にソートする場合は、スライスを使う
array([5, 4, 3, 2, 1])
>>> b=np.array([[1,3,5],          # 2次元配列の場合
                [6,4,2]])
>>> np.sort(b)                    # デフォルトでは最大次元の軸に沿ってソート
array([[1, 3, 5],
       [2, 4, 6]])
>>> np.sort(b, axis=0)            # axisでソートする軸を指定
array([[1, 3, 2],
       [6, 4, 5]])
>>> np.sort(b, axis=None)         # axis=Noneで1次元配列にして返す
array([1, 2, 3, 4, 5, 6])

参考:
Array manipulation routines — NumPy v1.13 Manual
Quickstart tutorial — NumPy v1.13 Manual

広告を非表示にする

<NumPy> 配列の確認

配列の属性

>>> import numpy as np
>>> a = np.array([[1,2,3],[4,5,6]])
>>> a.ndim   # 次元
2
>>> a.size   # 要素数
6
>>> a.shape  # 各次元の要素数
(2, 3)

要素へのアクセス

スライスが使える。
1次元配列の場合。

>>> b = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> b[1]       # 1番目
1
>>> b[1:7]     # 1番目から7番目まで
array([1, 2, 3, 4, 5, 6])
>>> b[1:7:2]   # 1番目から7番目まで2つ飛ばしで
array([1, 3, 5])
>>> b[3:]      # 3番目以降
array([3, 4, 5, 6, 7, 8, 9])
>>> b[-2]      # 末尾から2番目
8
>>> b[[0,5,7]] # リストで複数のインデックスを指定
array([0, 5, 7])


2次元配列の場合。

>>> c = np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12]])
>>> c
array([[ 1,  2,  3,  4],
       [ 5,  6,  7,  8],
       [ 9, 10, 11, 12]])
>>> c[1,1]     # (1, 1)要素
6
>>> c[0:2]     # 0~1行目
array([[1, 2, 3, 4],
       [5, 6, 7, 8]])
>>> c[:, 0:3]  # 0~2列目
array([[ 1,  2,  3],
       [ 5,  6,  7],
       [ 9, 10, 11]])
>>> c[0:2,1:3] # 0~1行目かつ1~2列目
array([[2, 3],
       [6, 7]])

参考:
The N-dimensional array (ndarray) — NumPy v1.12 Manual
Indexing — NumPy v1.12 Manual

広告を非表示にする