2  NumPy

NumPy は,数値計算を効率的に行うためのライブラリであり,多次元配列を扱うことができる.本書では,ベクトルや行列の計算,データの集計などに用いる.

通常,以下のようにインポートし,np という別名を付けて使用する.

import numpy as np

以降のコードでは,このインポートがすでに行われているものとする.

2.1 配列の作成

配列は,np.array() 関数を使って作成する.次のコードは,スカラーを作成する例である.

scalar = np.array(5)
print(scalar)
5

次のコードは,1次元配列を作成する例である.これは線形代数におけるベクトルに対応する.

a = np.array([1, 2, 3, 4, 5])
print(a)
[1 2 3 4 5]

次のコードは,2次元配列を作成する例である.これは線形代数における行列に対応する.

b = np.array([[1, 2, 3], [4, 5, 6]])
print(b)
[[1 2 3]
 [4 5 6]]

配列が何行何列かは,shape で確認できる.b は2行3列であるため,(2, 3) となる.

print(b.shape)
(2, 3)

練習 2.1 np.array() を使って,次の行列に対応する2次元配列を作成し,表示せよ.

\begin{bmatrix} 1 & 2 \\ 3 & 4 \end{bmatrix}

解答 2.1.

M = np.array([[1, 2], [3, 4]])
print(M)
[[1 2]
 [3 4]]

2.2 数列の生成

規則的に並んだ数の配列は,一つずつ書き並べなくても作成できる.

np.arange(a, b) は,a から b-1 までの整数を並べた配列を返す.range() と同じ規則である.

print(np.arange(1, 7))
[1 2 3 4 5 6]

np.linspace(a, b, n) は,a から b までを等間隔に区切った n 個の値を返す.np.arange() と違い,両端の ab を含む.

print(np.linspace(0, 1, 5))
[0.   0.25 0.5  0.75 1.  ]

np.linspace() は,グラフを描くときに横軸の値を作るためによく使う.

練習 2.2 np.linspace() を使って,-1 から 1 までを等間隔に区切った 5 個の値を作成し,表示せよ.

解答 2.2.

print(np.linspace(-1, 1, 5))
[-1.  -0.5  0.   0.5  1. ]

2.3 要素の取り出し

配列の要素は,[] の中に位置を書いて取り出す.位置は 0 から数えるため,先頭の要素は a[0] である.

a = np.array([10, 20, 30, 40, 50])

print(a[0])
print(a[2])
10
30

位置に負の値を書くと,末尾から数える.a[-1] は最後の要素である.

print(a[-1])
50

a[i:j] と書くと,i 番目から j-1 番目までをまとめて取り出せる.これをスライスという.

print(a[1:3])
[20 30]

2次元配列では,[行, 列] の順に位置を書く.次のコードは,0行2列目の要素を取り出す.

A = np.array([[1, 2, 3], [4, 5, 6]])

print(A[0, 2])
3

: は「すべて」を表す.A[:, 0] と書くと,すべての行の 0 列目が取り出せる.データから特定の列だけを取り出すときによく使う.

print(A[:, 0])
[1 4]

練習 2.3 上の2次元配列 A から,1行目の [4, 5, 6] を取り出して表示せよ.

解答 2.3.

print(A[1, :])
[4 5 6]

2.4 配列の演算

NumPy を使うと,配列同士の演算を簡単に行うことができる.例えば,2つの2次元配列の要素ごとの和を計算するには,以下のようにする.

A = np.array([[1, 2, 3], [4, 5, 6]])
B = np.array([[7, 8, 9], [10, 11, 12]])
C = A + B

print(C)
[[ 8 10 12]
 [14 16 18]]

この演算を数式で表現すると,以下のようになる.

\begin{bmatrix} 1 & 2 & 3 \\ 4 & 5 & 6 \end{bmatrix}+ \begin{bmatrix} 7 & 8 & 9 \\ 10 & 11 & 12 \end{bmatrix}= \begin{bmatrix} 8 & 10 & 12 \\ 14 & 16 & 18 \end{bmatrix}

練習 2.4 2つの1次元配列 a = [5, 7, 9]b = [1, 2, 3] を作成し,その差 a - b を求めよ.

解答 2.4.

a = np.array([5, 7, 9])
b = np.array([1, 2, 3])

print(a - b)
[4 5 6]

2.5 NumPy の関数

NumPy は様々な数学関数を提供しており,配列に対して簡単に適用できる.例えば,次のように np.sum() 関数を使って,配列の要素の合計を計算できる.

array = np.array([1, 2, 3])
total = np.sum(array)
print(total)
6

同じように,np.max() は最大値を,np.min() は最小値を返す.

print(np.max(array))
print(np.min(array))
3
1

2.6 乱数

np.random を使うと,乱数を含む配列を作成できる.手法を試すための架空のデータを作るときに用いる.

乱数は,実行するたびに異なる値になる.np.random.seed() に同じ値を与えておくと,毎回同じ乱数が得られる.本書では,実行結果を再現できるようにするため,乱数を使う前に np.random.seed(0) を置いている.

np.random.rand(n) は,0 以上 1 未満の一様乱数を n 個返す.

np.random.seed(0)
print(np.random.rand(3))
[0.5488135  0.71518937 0.60276338]

np.random.normal(mu, sigma, n) は,平均 mu,標準偏差 sigma の正規分布に従う乱数を n 個返す.正規分布については,確率統計の章で扱う.

np.random.seed(0)
print(np.random.normal(50, 10, 3))
[67.64052346 54.00157208 59.78737984]

np.random.randn(n) は,平均 0,標準偏差 1 の正規分布に従う乱数を n 個返す.

np.random.seed(0)
print(np.random.randn(3))
[1.76405235 0.40015721 0.97873798]

練習 2.5 平均 170,標準偏差 6 の正規分布に従う乱数を 5 個生成し,表示せよ.ただし,はじめに np.random.seed(0) を実行すること.

解答 2.5.

np.random.seed(0)
print(np.random.normal(170, 6, 5))
[180.58431408 172.40094325 175.8724279  183.4453592  181.20534794]