【Pandas】条件に一致する行にのみ処理を実行する -loc, mask(), where()

Pandasでデータの前処理をするときによくある処理に、「特定の条件に一致する行にのみに処理を加える」というのがあります(あると思います)。

今回はデータフレームに対して、ある条件に一致する行にのみ処理を実行する方法を紹介します。

前提

以下のようなデータフレームを準備します。ウォルマートの株価データです。

import pandas as pd

df = pd.read_csv("../data/walmart_stock.csv").set_index("Date").head(5)
df
元のデータフレーム

今回は”High”列の値が138以上の行に対して、新規列”judge”を作成し、値「OK」を格納します。目標にする結果は以下です。

処理後のデータフレーム
処理後のデータフレーム(出力したい結果)

処理方法

locを使う

locを使って条件に一致する行を抽出し、その行に対して値を代入することができます。

df.loc[df["High"]>=138, "judge"] = "OK"

“judge”列は元々のデータフレームには存在しませんが、このように指定することで新規列として作成することができます。

処理後のデータフレーム

df.mask()を使う

df.mask()を使うことでも同様の結果を得ることができます。

df["judge"] = df["High"].mask(df["High"]>=138, "OK")

上記例のイメージとしては、まず新規列”judge”に列”High”を代入します。その後、mask()の第一引数の条件に一致する行の値に対して、第二引数の値を代入します。

なので、locの場合と異なり、条件に一致しない行にも何かしら値が入ります。この場合が列”High”の値が入ります。

mask()を実行した結果

条件に一致しない行に値を入れたくなければ、予め空の列”judge”を作成し、そこに対して値を入れていくことで対応できます。

#空の列"judge"を作成
df["judge"] = None
df["judge"] = df["judge"].mask(df["High"]>=138, "OK")
処理後のデータフレーム

where()を使う

df.where()を使うことによっても、特定の行にのみ処理を実施することができます。

使い方はmask()と同じですが、第二引数に値を指定した場合、第一引数の条件に一致しない行に対してその値が代入されます。

df["judge"] = df["High"].where(df["High"]>=138, "NG")
where()の結果1

第一引数の条件に一致する行については、基本的に元の値が格納されます。

今回の目的の形にするためには、mask()同様に段階の処理が必要です。まずは、値が「OK」の列”judge”を作成します。その後、列”judge”に対して、where()を適用します。第二引数にはNoneを指定します。

df["judge"] = "OK"
df["judge"] = df["judge"].where(df["High"]>=138, None)
where()の結果2
where()の結果

今回のケースではやや遠回りなやり方になり、あまりオススメできません。。。

Pythonでデータサイエンスするなら

Pythonでデータサイエンスをするなら、以下の書籍がおすすめです。Pandas、matplotlib、Numpy、scikit-learnといったデータサイエンスに必要なライブラリを、体系立てて一通り学ぶことができます。

ややお値段高めですが、これ1冊で十分という内容・ボリュームなので、損はしないと思います^^

初学者の方にはこちらもオススメです^^

まとめ

Pandasデータフレームに対して、ある条件に一致する行にのみ処理を実行する方法を紹介しました。やり方はいくつかあり、それぞれ特徴があります。

条件に一致する行に対してなのか、一致しない行に対してなのかといったように、目的別にやり方を使い分けることで少ない処理数で実行できます。

ではでは👋