pandas.DataFrameで特定条件の行から単独の値だけ取得する際にハマったことのメモ。 まずは問題設定。以下のようなスクリプトでDataFrameから一つだけ値を取り出して色々操作したい。
import pandas as pd df = pd.DataFrame( { 'key': ['K0', 'K1', 'K2', 'K3', 'K4', 'K5'], 'A': [1, 2, 3, 4, 5, 6] } ) # "key"が"K0"の行の'A'の値を取り出す a = df[df["key"] == "K0"]["A"]
このとき、print(a)をすると図1のように表示される。
つまり、aはnumpy.int64などの値ではなく、型情報なども含まれているSeries型であることがわかる。なお、このことはtype(a)することでもわかる。
このように特定条件の行から値だけ取り出したつもりが、Series型であることによって引き起こされる問題はいくつかある。
例えば、下記のようなスクリプトは動かない。
df2 = pd.DataFrame( { 'key2': ['K0', 'K1', 'K2', 'K3', 'K4', 'K5'], 'B': [1, 2, 3, 4, 5, 6] } ) # df2から"B"がaである行を取り出す df2.query("B == {a}".format(a=a)) ''' 下記のようなValueErrorを吐く ValueError: multi-line expressions are only valid in the context of data, use DataFrame.eval '''
上記の問題をクリアする方法として、Series型から値だけを取り出す方法がある。具体的にはilocを使う。
import pandas as pd df = pd.DataFrame( { 'key': ['K0', 'K1', 'K2', 'K3', 'K4', 'K5'], 'A': [1, 2, 3, 4, 5, 6] } ) # # "key"が"K0"の行の'A'の値を取り出す # a = df[df["key"] == "K0"]["A"] ← ダメだったスクリプト b = df[df["key"] == "K0"]["A"].iloc[-1] #←使えるスクリプト
これで下記を実行するとちゃんと動く。
# df2から"B"がbである行を取り出す df2.query("B == {b}".format(b=b))
ということで、pandas.DataFrameの特定条件の行から単独の値を取り出すときは、iloc[-1]をしましょう!