NumPy:配列のスライシングとインデックス指定
NumPy 配列から特定の要素を取り出すには、スライシングとインデックス指定を使います。Python のリストと似ていますが、多次元配列でより強力に使えます。
基本的なインデックス指定
1次元配列では、Python のリストと同じようにインデックスで要素を取得できます。
import numpy as np
a = np.array([10, 20, 30, 40, 50])
print(a[0]) # 10(先頭)
print(a[-1]) # 50(末尾)
print(a[2]) # 30
2次元配列では、[行, 列] の形式で指定します。
a = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
print(a[0, 0]) # 1(0行0列)
print(a[1, 2]) # 6(1行2列)
print(a[2, 1]) # 8(2行1列)
スライシング
コロン : を使って範囲を指定します。start:stop で start から stop の手前まで取得します。
a = np.array([10, 20, 30, 40, 50])
print(a[1:4]) # [20 30 40](インデックス1〜3)
print(a[:3]) # [10 20 30](先頭から3つ)
print(a[2:]) # [30 40 50](インデックス2以降)
print(a[::2]) # [10 30 50](1つ飛ばし)
2次元配列でも同様に使えます。
a = np.array([[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12]])
# 0〜1行目、1〜2列目
print(a[0:2, 1:3])
# [[2 3]
# [6 7]]
# 全行、2列目以降
print(a[:, 2:])
# [[ 3 4]
# [ 7 8]
# [11 12]]
# 1行目のすべて
print(a[1, :]) # [5 6 7 8]
print(a[1]) # [5 6 7 8](同じ結果)
ファンシーインデックス
リストや配列で複数のインデックスを指定できます。これをファンシーインデックスと呼びます。
a = np.array([10, 20, 30, 40, 50])
# インデックス0, 2, 4の要素
print(a[[0, 2, 4]]) # [10 30 50]
2次元配列では、行と列それぞれにリストを渡します。
a = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
# (0,0), (1,1), (2,2) の要素(対角成分)
print(a[[0, 1, 2], [0, 1, 2]]) # [1 5 9]
ブールインデックス
条件式を使って要素を選択できます。
a = np.array([1, 5, 3, 8, 2, 9])
# 5より大きい要素
print(a[a > 5]) # [8 9]
# 偶数の要素
print(a[a % 2 == 0]) # [8 2]
条件を満たす要素だけを取り出せるので、データのフィルタリングに便利です。
# 条件に合う要素を書き換える
a = np.array([1, 5, 3, 8, 2, 9])
a[a > 5] = 0
print(a) # [1 5 3 0 2 0]
スライスはビューを返す
スライスで取得した配列は、元の配列のビュー(参照)です。変更すると元の配列も変わります。
a = np.array([1, 2, 3, 4, 5])
b = a[1:4]
b[0] = 99
print(a) # [ 1 99 3 4 5]
コピーが必要な場合は .copy() を使ってください。
a = np.array([1, 2, 3, 4, 5])
b = a[1:4].copy()
b[0] = 99
print(a) # [1 2 3 4 5](変わらない)