[Python] 行列やベクトルを扱うことができるNumPyに入門
こんにちは、@yoheiMuneです。
本日はPythonで行列やベクトルの演算ができるNumPyライブラリの基本的な使い方をブログに書きたいと思います。
さらに詳しく(ユニバーサル関数)
Python Numpy Tutorial | CS231n Convolutional Neural Networks for Visual Recognition
NumPy本家のサイト(英語)
本ブログでは、フロントエンド・Python・機械学習を中心に発信していきます。気になった方はぜひ、本ブログのRSSやTwitterをフォローして頂けると幸いです ^ ^。
最後までご覧頂きましてありがとうございました!
本日はPythonで行列やベクトルの演算ができるNumPyライブラリの基本的な使い方をブログに書きたいと思います。
目次
NumPyライブラリとは
NumPyは、Pythonで科学計算ができるライブラリで、線形代数などを扱うことができます。Pythonでの機械学習となるとほぼ必須のライブラリです。OctaveやMatlabほど直感的に行列演算ができないですが、色々と機能は用意されているので、それらについてブログで触れてみたいと思います。NumPyのインストール
インストールは簡単でpip
で行うことができます。$ pip install --upgrade numpyこれでインストールは完了です。
NumPyを使ってみる
ここからは具体的にNumPyを使ってみたいと思います。配列、ベクトル、行列を作成する
以下のようにすることで、色々とデータを作成することができます。import numpy as np # ベクトル a = np.array([1,2,3]) print(a) # [1 2 3] print(type(a)) # <class 'numpy.ndarray'> print(a.shape) # (3,) print(a[0], a[1], a[2]) # 1 2 3 # 行列 b = np.array([[1,2,3], [4,5,6]]) print(b) # [[1 2 3] # [4 5 6]] print(type(b)) # <class 'numpy.ndarray'> print(b.shape) # (2, 3) print(b[0,0], b[0,1], b[1,1]) # 1 2 5 # 各種便利に行列を作れる(ゼロ行列、単位行列、など) a = np.zeros((2,2)) print(a) # [[ 0. 0.] # [ 0. 0.]] b = np.ones((1,2)) print(b) # [[ 1. 1.]] c = np.full((2,2), 7) print(c) # [[ 7. 7.] # [ 7. 7.]] d = np.eye(2) print(d) # [[ 1. 0.] # [ 0. 1.]] e = np.random.random((2,2)) print(e) # [[ 0.35882145 0.82999821] # [ 0.58963763 0.58711411]]さらに詳しく
行列から部分行列を取り出す
要素を取り出すときに、範囲を指定して部分行列を取り出すことができます。import numpy as np # 配列の要素取得と同じ感じで、"a"の一部を取り出せる a = np.array([[1,2,3,4], [5,6,7,8], [9,10,11,12]]) b = a[:2, 1:3] print(b) # [[2 3] # [6 7]] # "b"は"a"への参照実装なので、書き換えると"a"も変わる print(a[0,1]) # 2 b[0,0] = 7 print(a[0,1]) # 7 # 取り出し方によって、ランク(Rank)が違う a = np.array([[1,2,3,4], [5,6,7,8], [9,10,11,12]]) # Rank1 row_r1 = a[1,:] print(row_r1) # [5 6 7 8] print(row_r1.shape) # (4,) # Rank2 row_r2 = a[1:2,:] print(row_r2) # [[5 6 7 8]] print(row_r2.shape) # (1, 4) # Rank1 col_r1 = a[:,1] print(col_r1, col_r1.shape) # [ 2 6 10] (3,) # Rank2 col_r2 = a[:,1:2] print(col_r2, col_r2.shape) # [[ 2] # [ 6] # [10]] (3, 1)
Integer Array Indexing
これはちょっと分かりづらいですが、便利です。行列から値を取り出す場合にa[[行一覧],[列一覧]]
で取り出すことができます。import numpy as np # 「a[[行一覧],[列一覧]]」で値を取り出す a = np.array([[1,2], [3,4], [5,6]]) print(a[[0,1,2], [0,1,0]]) # [1 4 5] # 以下でも同じ要素を取り出せる print(np.array([a[0,0], a[1,1], a[2,0]])) # [1 4 5] # もう一例 a = np.array([[1,2,3], [4,5,6], [7,8,9], [10,11,12]]) b = np.array([0,2,0,1]) print(a[np.arange(4), b]) # [ 1 6 7 11] # 以下のように値の更新にも使える a[np.arange(4), b] += 10 print(a) # [[11 2 3] # [ 4 5 16] # [17 8 9] # [10 21 12]]さらに詳しく
Boolean Array Indexing
条件に合致する要素のみを取り出すことができます。import numpy as np # 条件のTrue/Falseの行列を得ることができる a = np.array([[1,2], [3,4], [5,6]]) bool_idx = (a > 2) print(bool_idx) # [[False False] # [ True True] # [ True True]] # 上記を使って、条件がTrueの要素のみを取り出せる print(a[bool_idx]) # [3 4 5 6] # 以下のショートハンドでもOK print(a[a > 2]) # [3 4 5 6]
データ型
データ型の確認や指定をすることができます。import numpy as np a = np.array([1,2]) print(a.dtype) # int64 b = np.array([1.0,2.0]) print(b.dtype) # float64 c = np.array([1,2], dtype=np.uint8) print(c.dtype) # uint8さらに詳しく
ベクターや行列の演算
ベクターや行列について、四則演算や内積、外積などの計算を行うことができます。
import numpy as np
## 要素ごとの演算
a = np.array([[1,2], [3,4]])
b = np.array([[5,6], [7,8]])
# 足し算
print(a + b)
print(np.add(a,b))
# 引き算
print(a - b)
print(np.subtract(a,b))
# 掛け算
print(a * b)
print(np.multiply(a,b))
# 割り算
print(a / b)
print(np.divide(a,b))
# ルート
print(np.sqrt(a))
# 行列・ベクトルの演算
x = np.array([[1,2], [3,4]])
y = np.array([[5,6], [7,8]])
v = np.array([9,10])
w = np.array([11,12])
# 内積
print(v.dot(w))
print(np.dot(v, w))
# 外積(行列 × ベクトル)
print(x.dot(w))
print(np.dot(x, w))
# 外積(行列 × 行列)
print(x.dot(y))
print(np.dot(x, y))
# 要素の値の合計
x = np.array([[1,2], [3,4]])
print(np.sum(x))
print(np.sum(x, axis=0)) # compute sum of each column.
print(np.sum(x, axis=1)) # compute sum of each row.
# 転置
x = np.array([[1,2], [3,4]])
print(x.T)
v = np.array([1,2,3])
print(v.T) # これは意味ない(.T
する前と一緒)
# ベクトル同士の外積
v = np.array([1,2,3])
w = np.array([4,5])
print(np.reshape(v, (3,1)) * w) # 3×2行列
さらに詳しくさらに詳しく(ユニバーサル関数)
ブロードキャスト
ブロードキャスト機能もあります。import numpy as np #1: for文を使ったブロードキャスト(処理速度が遅い) x = np.array([[1,2,3], [4,5,6], [7,8,9], [10,11,12]]) v = np.array([1,0,1]) y = np.empty_like(x) # Create an empty matrix with the same shape as "x" for i in range(4): y[i,:] = x[i,:] + v #2: 同じ次元の行列を作って足す(これはこれで良い) x = np.array([[1,2,3], [4,5,6], [7,8,9], [10,11,12]]) v = np.array([1,0,1]) y = np.empty_like(x) vv = np.tile(v, (4,1)) y = x + vv #3: ブロードキャスト(xの各行にvを足す) x = np.array([[1,2,3], [4,5,6], [7,8,9], [10,11,12]]) v = np.array([1,0,1]) y = x + v # ブロードキャスト(xの各列にwを足す) x = np.array([[1,2,3], [4,5,6]]) w = np.array([4,5]) y = (x.T + w).T # ブロードキャスト(xの各列にwを足す)(別ソリューション) y = x + np.reshape(w, (2,1)) # 各要素に実数を掛ける x = np.array([[1,2,3], [4,5,6]]) y = x * 2さらに詳しく
参考資料
今回の内容については、以下の2つを参照しました。ありがとうございます。Python Numpy Tutorial | CS231n Convolutional Neural Networks for Visual Recognition
NumPy本家のサイト(英語)
最後に
今回はNumPyの入門として、いろいろな使い方をブログに書きました。行列演算を高速に行えるのは素敵ですね。今後のマシーンラーニングの学習や実装に大いに役立てられそうです。本ブログでは、フロントエンド・Python・機械学習を中心に発信していきます。気になった方はぜひ、本ブログのRSSやTwitterをフォローして頂けると幸いです ^ ^。
最後までご覧頂きましてありがとうございました!