初心者データサイエンティストの備忘録

調べたことは全部ここに書いて自分の辞書を作る

pandas.DataFrameの特定条件の行から値だけ取得する方法

 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のように表示される。

f:id:aisinkakura_datascientist:20220317003409j:plain:w300
図1:print(a)の結果

つまり、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]をしましょう!