pandasのSeriesのファンシーインデックスで参照と代入

pandasのSeriesは、NumPyのndarrayと同様に [] の中にインデックス1つ書く代わりにインデックスの配列を書くと、その配列に対応して要素をピックアップしたSeriesを新しく作ってくれる。

import pandas as pd

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

インデックスの順番を守る必要はない。

print(sr1[[3, 2, 4]])
# 出力結果
# 3    30
# 2    20
# 4    40
# dtype: int64

要素が重複しても大丈夫みたい。

print(sr1[[3, 2, 2, 4]])
# 出力結果
# 3    30
# 2    20
# 2    20
# 4    40
# dtype: int64

インデックスが文字列のSeriesに対してもできる。

nan = float("nan")

sr2 = pd.Series([0.5, 0.8, nan], index=['foo', 'bar', 'baz'])
print(sr2)
# 出力結果
# foo    0.5
# bar    0.8
# baz    NaN
# dtype: float64

print(sr2[['baz', 'foo']])
# 出力結果
# baz    NaN
# foo    0.5
# dtype: float64

インデックスが文字列のSeriesに対して整数で指定することもできる。

print(sr2[[0, 2]])
# 出力結果
# foo    0.5
# baz    NaN
# dtype: float64

ファンシーインデックスで得たSeriesはもとのSeriesから必要な要素をコピーして作成される新しいSeriesであって、従って新しいSeriesを書き換えても、もとのSeriesには影響しない。

sr1 = pd.Series([0, 10, 20, 30, 40, 50])

# ファンシーインデックスで新しいSeriesを作成
sr1b = sr1[[1, 3, 4]]
print(sr1b)
# 出力結果
# 1    10
# 3    30
# 4    40
# dtype: int64

# 新しいSeriesの要素に代入
sr1b[1] = 100
print(sr1b)
# 出力結果
# 1    100
# 3     30
# 4     40
# dtype: int64

# 存在しないSeriesの要素に代入
sr1b[2] = 200
print(sr1b)
# 出力結果
# 1    100
# 3     30
# 4     40
# 2    200
# dtype: int64

# もとのSeriesは変わらず
print(sr1)
# 出力結果
# 0     0
# 1    10
# 2    20
# 3    30
# 4    40
# 5    50
# dtype: int64

NumPy配列と同様にファンシーインデックスは参照だけでなく、代入もできる。ファンシーインデックスでの代入は複数の要素をまとめて書き換えることができる。この場合のファンシーインデックスは新しいSeriesを生成するわけではない。

sr1 = pd.Series([0, 10, 20, 30, 40, 50])

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

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

sr1[[1, 4, 5]] = 999
print(sr1)
# 出力結果
# 0      0
# 1    999
# 2     20
# 3    300
# 4    999
# 5    999
# dtype: int64

関連

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