pythonのpandasにて、dataframe内のある要素が照合用のリストに含まれているかどうか確認したい時、listと同じように"in"で比較したいなあ(でもできないなあ)とか思ってたんですが、これ、.isin()できるんですね。って話を備忘録にします。
過去記事で「あんまり細かいtipsは記事化してもキリがないなあとは思っているので、コーディングの諸々に関するネタはあんまり書かないつもり云々」とか言っといてアレですが、そこはまあ、はい。
listをinで比較するやつ
listの場合、ある要素がリストに含まれているかどうかは"in"で確認することができます。"not in"で含まれていないことも確認できます。
holiday = ["Sat","Sun"] print("is holiday") print(" Mon : ", "Mon" in holiday) print(" Sat : ", "Sat" in holiday) print("\nis not holiday") print(" Mon : ", "Mon" not in holiday) print(" Sat : ", "Sat" not in holiday)
is holiday Mon : False Sat : True is not holiday Mon : True Sat : False
pandasでも同じことをやってみる
で、pandasでも同じことができないか考えてみます。ある列を基準に、照合用のリストに要素が含まれていればTrue,そうでなければFalseを返してほしい、という感じです。
以下のようなテーブルを例にします。
import pandas as pd import numpy as np df = pd.DataFrame([["Mon","Tue","Mon","Fri","Sat","Sun","Tue","Fri","Mon"], [120,150,200,90,140,180,150,150,120]]).T df.columns = ["Day","Sales"] df
Day | Sales | |
---|---|---|
0 | Mon | 120 |
1 | Tue | 150 |
2 | Mon | 200 |
3 | Fri | 90 |
4 | Sat | 140 |
5 | Sun | 180 |
6 | Tue | 150 |
7 | Fri | 150 |
8 | Mon | 120 |
まず大前提として、なんとなく適当に書いてみた以下のコードは動きません。
holiday = ["Sat","Sun"] df["Day"] in holiday
--------------------------------------------------------------------------- ValueError Traceback (most recent call last) <ipython-input-22-0b9535e475c1> in <module>() ----> 1 df["Day"] in holiday /usr/local/lib/python3.6/dist-packages/pandas/core/generic.py in __nonzero__(self) 1325 def __nonzero__(self): 1326 raise ValueError( -> 1327 f"The truth value of a {type(self).__name__} is ambiguous. " 1328 "Use a.empty, a.bool(), a.item(), a.any() or a.all()." 1329 ) ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
正しくは、こう。pandasのisin()メソッドを使います。
holiday = ["Sat","Sun"] df["Day"].isin(holiday)
0 False 1 False 2 False 3 False 4 True 5 True 6 False 7 False 8 False Name: Day, dtype: bool
「含まない」場合は、結果の否定を取れば良いです。
holiday = ["Sat","Sun"] ~df["Day"].isin(holiday)
0 True 1 True 2 True 3 True 4 False 5 False 6 True 7 True 8 True Name: Day, dtype: bool
ちなみにこれを調べた目的は、以下のように変数の水準を新たな別の変数にまとめる処理をしたかったからです。
holiday = ["Sat","Sun"] df["is_holiday"] = np.where(df["Day"].isin(holiday), True, False) df
Day | Sales | is_holiday | |
---|---|---|---|
0 | Mon | 120 | FALSE |
1 | Tue | 150 | FALSE |
2 | Mon | 200 | FALSE |
3 | Fri | 90 | FALSE |
4 | Sat | 140 | TRUE |
5 | Sun | 180 | TRUE |
6 | Tue | 150 | FALSE |
7 | Fri | 150 | FALSE |
8 | Mon | 120 | FALSE |
おわりに
大したことではない話ですが、「あ、こんなんできるんだ」と思ったので備忘録として。Pythonは誰に習ったわけでもなく我流でなんとなく書いているので、基礎知識がすっぽり抜け落ちている感否めません。