pandasのSeriesのブールインデックス参照

pandasのSeriesの要素参照に使う [] の中にインデックスを書く代わりに論理値(True/False)の配列を書くとその論理値がTrueに該当する箇所の要素をピックアップしたSeriesを新しく作ってくれる。

[]の中の論理値配列は普通のPython配列でもNumPyの配列でもよいし、論理値を要素に持つpandasのSeriesでもよい。 NumPy配列のブールインデックス参照では、[]の中の配列はNumPyの配列でないといけなくて、普通のPython配列ではだめなようなのだが。

import numpy as np
import pandas as pd

sr1 = pd.Series([0, 10, 20, 30, 40, 50])
print(sr1)
# 出力結果
# 0     0
# 1    10
# 2    20
# 3    30
# 4    40
# 5    50
# dtype: int64

# ブールインデックス参照の例

print(sr1[[False, True, False, False, False, True]])
# 出力結果
# 1    10
# 5    50
# dtype: int64

print(sr1[np.array([False, True, False, False, False, True])])
# 出力結果
# 1    10
# 5    50
# dtype: int64

print(sr1[pd.Series([False, True, False, False, False, True])])
# 出力結果
# 1    10
# 5    50
# dtype: int64

sr1 % 20 == 0 のように書くと、NumPyのベクトル計算と同様にSeriesでもベクトル計算ができ、論理値のSeriesが生成されるので、それをそのまま [] の中に書くことによってフィルタ処理のようなことができる。

# ベクトル計算
print(sr1 % 20 == 0)
# 出力結果
# 0     True
# 1    False
# 2     True
# 3    False
# 4     True
# 5    False
# dtype: bool

ベクトル計算の結果をそのままブールインデックス参照に使う例。SeriesはNumPyの配列と違ってインデックスを保持するので、インデックスに欠番が生じる。

print(sr1[sr1 % 20 == 0])
# 出力結果
# 0     0
# 2    20
# 4    40
# dtype: int64

参照だけでなく、代入もできる。ブールインデックスでの代入は複数の要素をまとめて書き換えることができる。

sr1[sr1 % 20 == 0] = [0, 200, 400]
print(sr1)
# 出力結果
# 0      0
# 1     10
# 2    200
# 3     30
# 4    400
# 5     50
# dtype: int64

要素の数が合わないとエラーになる。

sr1[sr1 % 20 == 0] = [0, 200, 400, 600]
# 以下のエラーが発生
# ValueError: Length of replacements must equal series length

ブールインデックスに配列ではなく数値を代入すると、ブールインデックスで参照されている要素にすべて同一の値が代入される。

sr1[sr1 % 20 == 0] = 1000
print(sr1)
# 出力結果
# 0    1000
# 1      10
# 2    1000
# 3      30
# 4    1000
# 5      50
# dtype: int64

関連

このサイトは筆者(hydrocul)の個人メモの集合です。すべてのページは永遠に未完成です。