Pandasでデータの前処理をするときによくある処理に、「特定の条件に一致する行にのみに処理を加える」というのがあります(あると思います)。
今回はデータフレームに対して、ある条件に一致する行にのみ処理を実行する方法を紹介します。
前提
以下のようなデータフレームを準備します。ウォルマートの株価データです。
import pandas as pd
df = pd.read_csv("../data/walmart_stock.csv").set_index("Date").head(5)
今回は”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”の値が入ります。
条件に一致しない行に値を入れたくなければ、予め空の列”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")
第一引数の条件に一致する行については、基本的に元の値が格納されます。
今回の目的の形にするためには、mask()同様に段階の処理が必要です。まずは、値が「OK」の列”judge”を作成します。その後、列”judge”に対して、where()を適用します。第二引数にはNoneを指定します。
df["judge"] = "OK"
df["judge"] = df["judge"].where(df["High"]>=138, None)
今回のケースではやや遠回りなやり方になり、あまりオススメできません。。。
Pythonでデータサイエンスするなら
Pythonでデータサイエンスをするなら、以下の書籍がおすすめです。Pandas、matplotlib、Numpy、scikit-learnといったデータサイエンスに必要なライブラリを、体系立てて一通り学ぶことができます。
ややお値段高めですが、これ1冊で十分という内容・ボリュームなので、損はしないと思います^^
初学者の方にはこちらもオススメです^^
まとめ
Pandasデータフレームに対して、ある条件に一致する行にのみ処理を実行する方法を紹介しました。やり方はいくつかあり、それぞれ特徴があります。
条件に一致する行に対してなのか、一致しない行に対してなのかといったように、目的別にやり方を使い分けることで少ない処理数で実行できます。
ではでは👋