Skip to content

4. データ操作の基礎 - NumPy

第 4 回ではデータ操作の基礎として、NumPy の基本的な使い方を紹介します。

4.1NumPy の概要

NumPy は、Python で効率的に数値計算を行うための強力なライブラリです。特に NumPy の配列用の型である ndarray は、Python のリストよりも簡単に記述でき、メモリ効率が高く演算も高速になります。また、NumPy はさまざまなデータ分析・機械学習ライブラリの土台にもなっています。

4.1.1 NumPy のインポート

NumPy は以下のようにインポートして使います。

import numpy as np

4.2 配列の作成

NumPy における配列 (ndarray) は、以下のようにして作成することができます。

ndarray の作成
import numpy as np

# 1 次元配列
arr1 = np.array([1, 2, 3, 4])

# 2 次元配列
arr2 = np.array([[1, 2], [3, 4]])

# 特殊な配列
arr3 = np.zeros((2, 3))     # 0 で埋めた 2×3 の配列
arr4 = np.ones(5)           # 1 で埋めた 1 次元配列
arr5 = np.arange(0, 10, 2)  # [0, 2, 4, 6, 8]
arr6 = np.linspace(0, 1, 5) # [0, 0.25, ..., 1]

# 配列の表示('\n' は改行を意味)
print("arr1:\n", arr1)
print("arr2:\n", arr2)
print("arr3:\n", arr3)
print("arr4:\n", arr4)
print("arr5:\n", arr5)
print("arr6:\n", arr6)
Output
arr1:
 [1 2 3 4]
arr2:
 [[1 2]
 [3 4]]
arr3:
 [[0. 0. 0.]
 [0. 0. 0.]]
arr4:
 [1. 1. 1. 1. 1.]
arr5:
 [0 2 4 6 8]
arr6:
 [0.   0.25 0.5  0.75 1.  ]

4.3 配列の基本操作

4.3.1 配列の形状変更

NumPy の配列の形状は、numpy.shape() 関数で確認し、numpy.reshape() 関数で変更することができます。

ndarray の形状変更
reshaped = np.reshape(arr1, (2, 2))
print(reshaped)
Output
[[1 2]
 [3 4]]

上の例は、reshaped = arr1.reshape((2, 2)) と書き直すこともできます。

4.3.2 配列の結合

複数の配列を結合する場合は、numpy.concatenate() 関数を使います。ただし、結合する配列の形状(軸のサイズ)が同じでないとエラーが出るので注意してください。

ndarray の結合
concat = np.concatenate((arr1, arr4))
print(concat)
Output
[1. 2. 3. 4. 1. 1. 1. 1. 1.]

4.3.3 配列の平坦化

多次元配列を一次元に平坦化するには、numpy.ndarray.flatten() 関数を使います。

二次元配列の一次元化
flat = arr2.flatten()
print(flat)
Output
[1 2 3 4]

4.4 配列演算とブロードキャスト

NumPy の配列は、以下のような単純な計算式で、各要素に対する演算を行うことができます。このような異なる形状(次元)の配列同士を自動的に形を合わせて計算する仕組みを、ブロードキャストと呼びます。

配列のブロードキャスト
# 各要素を2倍
arr = np.array([10, 20, 30])
print("arr * 2:\n", arr * 2)

# 各要素に 10 を加算
matrix = np.array([[1, 2], [3, 4]])
print("\nmatrix + 10:\n", matrix + 10)

# 1 次元配列と 2 次元配列のブロードキャスト
mat = np.array([[1, 2, 3], [4, 5, 6]])
vec = np.array([10, 20, 30])
print("\nmat + vec:\n", (mat + vec))
Output
arr * 2:
 [20 40 60]

matrix + 10:
 [[11 12]
 [13 14]]

mat + vec:
 [[11 22 33]
 [14 25 36]]

4.5 インデックスとスライス

4.5.1 インデックス

NumPy の配列は、リストと同様にインデックスを使って要素を取得することができます。インデックスは 0 からはじまり、負の数値を指定すると配列の最後からアクセスできます。

インデックスによる要素の取得
arr = np.array([10, 20, 30, 40, 50])
print(arr[0])  # 出力: 10
print(arr[-1]) # 出力: 50

mat = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print(mat[0, 1])  # 出力: 2
print(mat[2, -1]) # 出力: 9

4.5.2 スライス

スライスを使うと、複数の要素をまとめて取得することができます。

  • スライスは、[開始:終了] または [開始:終了:ステップ] の形式で指定します。
  • [開始] を省略すると 0 から、[終了] を省略すると最後まで取得します。
  • [ステップ] を省略すると 1 になります。
一次元配列のスライス
arr = np.array([10, 20, 30, 40, 50])
print(arr[1:4])   # 出力: [20 30 40]
print(arr[:3])    # 出力: [10 20 30]
print(arr[2:])    # 出力: [30 40 50]
print(arr[::2])   # 出力: [10 30 50]

多次元配列についても同様に、スライスによって配列の一部をまとめて取得することができます。

二次元配列のスライス
mat = np.array([
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]]
)
print(mat[1, :])      # 出力: [4 5 6]
print(mat[1:, :])     # 出力: [[4 5 6], [7 8 9]]
print(mat[:, 2])      # 出力: [3 6 9]
print(mat[:, :2])     # 出力: [[1 2], [4 5], [7 8]]
print(mat[1:, :2])    # 出力: [[4 5], [7 8]]
print(mat[:, [0, 2]]) # 出力: [[1 3], [4 6], [7 9]]

4.6 条件抽出

条件に従った要素の抽出も簡単に行うことができます(ブールインデックス)。例えば、15 より大きい要素のみ抽出したい場合は以下のようにします。

二次元配列のスライス
arr = np.array([10, 20, 30])
print(arr[arr > 15])
Output
[20 30]

その他にも NumPy には多くの便利な関数が用意されていますので、適宜ドキュメントを参照するようにしてください。

演習

演習 4-1

都道府県データ (prefecture_data) に対し、人口が250万人以上の都道府県を抽出してください。また、結果を棒グラフで可視化してください。

演習 4-1

都道府県データ (prefecture_data) に対し、横軸が緯度、縦軸が人口密度の散布図を作成してください。