どうも~むるむるです~
この記事では数値計算によく使われるPythonのライブラリであるnumpyについてのよく使う機能をまとめていきたいと思います.
機械学習をPythonで実装したいならnumpyはまず間違いなく使うことになります.この記事でしっかりと基礎を抑えてしまいましょう.
numpyの基本とnumpyを使った行列・ベクトルの計算に関してはこちらの記事をご覧ください.
数学でよく使う関数:ルート,sin,指数関数,対数関数など
数学でよく使われる関数はnumpyで使うことができます.例えば以下のような関数です.以下の他にもcos,やlog2(底が2の対数)など様々な関数が用意されています.
# よく使う関数 a = [1, 2, np.pi] print(np.sqrt(a)) print(np.sin(a)) print(np.log(a))# 自然対数 print(np.exp(a)) ''' 出力結果: [1. 1.41421356 1.77245385] [8.41470985e-01 9.09297427e-01 1.22464680e-16] [0. 0.69314718 1.14472989] [ 2.71828183 7.3890561 23.14069263] '''
0, 1だけのndarrayや単位行列の生成
数値計算をするときに,0や1だけを含む配列を作りたくなることはよくあります.
np.zeros( )やnp.ones( )を使うことで,次元ごとの要素数(shape)を指定して0や1だけのndarrayを生成することができます.
# 0,1だけのndarray shape = (3, 4) print(np.zeros(shape)) print('---') print(np.ones(shape)) ''' 出力結果: [[0. 0. 0. 0.] [0. 0. 0. 0.] [0. 0. 0. 0.]] --- [[1. 1. 1. 1.] [1. 1. 1. 1.] [1. 1. 1. 1.]] '''
n×nの単位行列はnp.eye(n)として以下のように作れます.
print(np.eye(3)) ''' 出力結果: [[1. 0. 0.] [0. 1. 0.] [0. 0. 1.]] '''
既存のndarrayと同じshapeの0だけを含んだndarrayは以下のようにして生成できます.
# 同じ形状のndarrayを生成 A = np.ones((3, 4)) B = np.zeros_like(A)# Aのshapeと同じshapeの0だけを含むndarrayを生成 print(A) print('---') print(B) ''' 出力結果: [[1. 1. 1. 1.] [1. 1. 1. 1.] [1. 1. 1. 1.]] --- [[0. 0. 0. 0.] [0. 0. 0. 0.] [0. 0. 0. 0.]] '''
次元(ndim),次元ごとの要素数(shape),全要素数(size)の確認
コードを書いていて変数の次元や次元ごとの要素数がわからなくなってしまい,確認したいということは多々あります.
そういう場合は,以下のようにして調べることができます.
# 次元(ndim),次元ごとの要素数(shape),全要素数(size) A = np.ones((3,4,5)) print(A.ndim) print(A.shape) print(A.size) ''' 出力結果: 3 (3, 4, 5) 60 '''
等差数列の生成
numpyではrange関数のように連続した数値を等間隔で持つような配列を簡単に生成することができます.
# 等差数列 print( np.arange(0, 2, 0.5) )# (開始,終わり,公差)の順 print( np.linspace(0, 2, 5) )# (開始,終わり,要素数)の順 ''' 出力結果: [0. 0.5 1. 1.5] [0. 0.5 1. 1.5 2. ] '''
np.arange( )はrange関数のnumpyバージョンです.range関数と同様,終わりとして選んだ数値は含まれないので気を付けましょう.
ndarrayを結合する
複数のデータを結合したいときなど,ndarrayを結合したくなったときは,以下のようにできます.水平方向にデータを結合したいときはnp.hstack(),垂直方向に結合したいときはnp.vstack( )を使います.
以下の例では,水平方向に結合した場合は横に広がっており,垂直方向に結合したときは縦に広がっているのが見て取れると思います.
# ndarrayの結合 a = np.zeros((3, 2))## 全部0 b = np.ones((3, 1))## 全部1 c = np.ones((1, 2)) + 1# 全部2 h = np.hstack((a, b))# 水平方向(horizontal)に連結 v = np.vstack((a, c))# 垂直方向(vertical)に連結 print('---h---') print(h) print('---v---') print(v) ''' 出力結果: ---h--- [[0. 0. 1.] [0. 0. 1.] [0. 0. 1.]] ---v--- [[0. 0.] [0. 0.] [0. 0.] [2. 2.]] '''
また,別の方法として,np.concatenate( ) では軸(axis)を指定して結合するという方法もあります.
まず以下の例を見てください.
# ndarrayの結合 a = np.zeros((3, 2))## 全部0 b = np.ones((3, 1))## 全部1 c = np.ones((1, 2)) + 1# 全部2 c0 = np.concatenate((a, c), axis = 0) # 軸を指定して連結 c1 = np.concatenate((a, b), axis = 1) # 軸を指定して連結 print('---c0---') print(c0) print('---c1---') print(c1) ''' 出力結果: ---c0--- [[0. 0.] [0. 0.] [0. 0.] [2. 2.]] ---c1--- [[0. 0. 1.] [0. 0. 1.] [0. 0. 1.]] '''
axisの指定について
「a」のaxisは以下のようになっています.「a = np.zeros((3, 2))」と初期化していることから,axis = 0 の方向に3つ0が並んで, axis = 1の方向に0が2つ並んでいることからも,軸の方向がわかると思います.

「c0」は「axis = 0」と指定してndarrayを結合しています.「c0」の出力を見れば「axis = 0」の方向にデータが 結合されていることがわかると思います.
np.concatenate()を使えば,データが高次元の時でも,軸を指定することで簡単にndarray同士を結合することができます.
ちなみにこの軸(axis)を指定する考え方はnumpyを使う上ではよく出てくるので慣れておきましょう.
要素の総和,積,平均,標準偏差を出す
ndarrayの要素の総和(summation),積(product),平均(mean),標準偏差(standard deviation)は以下のようにして計算できます.
# 要素をすべて足し合わせる,掛け合わせる,平均を取る,標準偏差を取る a = np.array([1, 2, 3, 4]) print(a.sum())# 足し合わせ print(a.prod())# 掛け合わせ print(a.mean())# 平均 print(a.std())# 標準偏差 ''' 出力結果: 10 24 2.5 1.118033988749895 '''
axisの指定
データが高次元のときは軸を指定することによって,その軸の総和,積,平均,標準偏差を出すことができます.
下のコードで確認してみてください
# 軸を指定して要素をすべて足し合わせる,掛け合わせる,平均を取る,標準偏差を取る A = np.array([[1, 2, 3], [4, 5, 6]]) print(A.sum(axis = 0))# 0次元目の合計 print(A.prod(axis = 1))# 1次元目の積 print(A.mean(axis = 0)) print(A.mean(axis = -1)) ''' 出力結果: [5 7 9] [ 6 120] [2.5 3.5 4.5] [2. 5.] '''
最大値・最小値
ndarrayの要素の最大値,最小値は「.max()」と「.min()」で求められます.axisを指定することもできます.
# 最大値,最小値 A = np.array([[1, 2, 3], [4, 5, 6]]) print(A.max()) print(A.min(axis = 1)) ''' 出力結果: 6 [1 4] '''
乱数の生成
numpyでは様々な確率分布から乱数の生成が行えます.今回は一様確率分布と正規分布から乱数を生成する方法だけをまとめました.
r = np.random.random((3, 2))# 0-1の乱数を生成し,shapeが(3,2)のndarrayを作る u = np.random.uniform(0, 10, (2, 3))# 0-10の一様確率分布から乱数を生成し,shapeが(2,3)のndarrayを作る n = np.random.normal(0, 1, (1, 4))# 平均0標準偏差1の正規分布からshapeが(1,4)のndarrayを作る print(r) print('=====') print(u) print('=====') print(n) ''' 出力結果: [[0.44361768 0.88737745] [0.82824834 0.70274631] [0.65953004 0.52618643]] ===== [[5.00661887 1.50750763 8.67954302] [1.39348131 9.78807614 3.39872563]] ===== [[-0.13770501 -0.35254858 0.25760754 0.18036636]] '''
ndarrayの形を変える: reshape
ndarrayのshapeを変更したいときは「.reshape(新しいshape)」が使えます.以下を見てみましょう
x = np.array([[1,2,3],[4,5,6]]) print(x) print('=====') print(x.reshape((3, 2)))# shapeを(3,2)に変更 print('=====') print(x.reshape((1, -1)))# shapeの最初を1に設定し,二つ目は自動で推測される ''' 出力結果: [[1 2 3] [4 5 6]] ===== [[1 2] [3 4] [5 6]] ===== [[1 2 3 4 5 6]] '''
「x」のshapeは(2, 3)であることに注意してください.
「x.reshape((3, 2))」では
「x.reshape((3, 2))」では もともと(2, 3)だったshapeを(3, 2)に変更しています.これはそのままでわかりやすいですね.
次の「x.reshape((1, -1))」について考えてみましょう.reshape()を使うときは1つの次元に限って,-1を指定することができるのですが,こうすることで他に指定された次元の要素数から-1とした次元の要素数を推測させることができます.
上の例ではデータ全体の要素数は3×2で6なので,一つ目の次元が1であると指定された場合残りの次元の要素数は6であると推測できます.
確認クイズ
クイズ1
変数「a」,「b」,「c」のうちいずれかをうまく結合して下のようなndarrayを作ってください
a = np.zeros((4, 3))## 全部0 b = np.ones((4, 1))## 全部1 c = np.ones((3, 2)) # 全部1 ''' # 以下の配列をつくってね [[0. 0. 0. 1.] [0. 0. 0. 1.] [0. 0. 0. 1.] [0. 0. 0. 1.]] '''
クイズ2
以下の変数「a」の次元数,次元ごとの要素数(shape),全体の要素数(size),行ごとの平均,列ごとの最小値を求めてください.
a = np.array([[1, 1, 1], [2, 3, 4] ])
次回
次回は「numpy:ブロードキャスト」について学習します.
ブロードキャストはnumpyで数値計算をする上で非常に大事なことですが,意外としっかり理解している人は少ないように感じます.これを知っているか知らないかでデバッグの効率など格段に変わるので知らない人は必ず理解しましょう.
次の記事はこちら.
機械学習のためにしっかりとPythonを勉強したいなら,ある程度の基礎を身に着けた後に下の本を読むのがお勧めです.この本をこなせば,より高いレベルへ到達できるでしょう.