NumPyの配列は「計算できるリスト」
以前のレッスンでリストを学び、「複数の値をひとまとまりとして扱う」という考え方が、後で学ぶベクトルに近いと説明しました。ここで登場するのが NumPy というライブラリです。
ライブラリ とは、他の人が作って公開している、便利な関数などをまとめた道具箱のことです。自分で一から作らなくても、importと書くだけで使えるようになります。NumPyは、数値計算を速く簡単に行うための、Pythonで最もよく使われるライブラリの一つです。
まず、Pythonの標準のリストで、全ての要素を2倍にしたいとします。
scores = [80, 65, 90]
doubled = []
for s in scores: # for文で1つずつ取り出して
doubled.append(s * 2) # 2倍した値を追加していく
# doubled は [160, 130, 180]
NumPyの配列を使うと、同じことがずっとシンプルに書けます。
import numpy as np # NumPyを「np」という短い名前で使えるようにする
scores = np.array([80, 65, 90])
doubled = scores * 2 # [160, 130, 180] が一括で計算される
for文を書かずに、配列全体に対して* 2と書くだけで、各要素が2倍になります。このように配列全体に対する計算を一括で行えることが、NumPyの一番の特長です(ベクトル化と呼ばれますが、名前は覚えなくて大丈夫です)。裏側では高速な処理が行われており、大量のデータを扱う機械学習では、この速さが重要になります。
配列同士の計算と統計関数
NumPyの配列は、配列同士の計算もできます。
import numpy as np
a = np.array([1, 2, 3])
b = np.array([10, 20, 30])
a + b # [11, 22, 33] (同じ位置同士を足す)
a * b # [10, 40, 90] (同じ位置同士を掛ける)
このように、同じ位置(インデックス)の要素同士で計算が行われます。これは、後の単元で学ぶ「ベクトルの足し算・掛け算」と全く同じ考え方です。
また、NumPyには統計に関する便利な関数も用意されています。
scores = np.array([80, 65, 90, 72, 88])
scores.mean() # 平均: 79.0
scores.max() # 最大値: 90
scores.min() # 最小値: 65
scores.sum() # 合計: 395
以前、for文を使って合計や平均を自分で計算しましたが、NumPyを使えばこのように1行で計算できます。今後のレッスンでは、こうしたNumPyの機能を土台として、データの前処理・可視化・機械学習のモデルの計算まで進んでいきます。
表の形の配列と、一部を取り出す書き方
ここまでの配列は、数値が1列に並んだものでした。機械学習では、「1人分のデータに、勉強時間と睡眠時間の2つの数値がある」のように、表の形(行と列) のデータをよく扱います。NumPyでは、リストの中にリストを入れて表します。
import numpy as np
X = np.array([[1, 8], # 1人目: 勉強1時間、睡眠8時間
[2, 7], # 2人目: 勉強2時間、睡眠7時間
[3, 6]]) # 3人目: 勉強3時間、睡眠6時間
X.shape # → (3, 2): 3行 × 2列
内側のリスト1つが表の 1行(1人分のデータ)です。shape(シェイプ、形)を見ると、「何行 × 何列か」が分かります。
番号を2つ重ねて、1つの値を取り出す
X[0] # → [1, 8]: 0番目の行(1人目のデータ)
X[0][1] # → 8 : 0番目の行の、1番目の値(1人目の睡眠時間)
X[0]で行を取り出し、続けて[1]でその行の中の値を取り出しています。番号はどちらも0から数えます。
範囲を指定して、まとめて取り出す
scores = np.array([80, 65, 90, 72, 88])
scores[:3] # → [80, 65, 90]: 先頭から3つ
X[:2] # → [[1, 8], [2, 7]]: 先頭から2行
[:3]は「先頭から3つ目まで」という意味です。たくさんのデータのうち、最初のいくつかだけを確認したいときによく使います。
次の章で使うscikit-learnは、入力データをこの表の形で受け取ります。データの項目が勉強時間の1つだけのときも、[[1], [2], [3]]のように「1列だけの表」にして渡します。