#はじめに
pandasで0-1フラグを作っている際、whereメソッドを使ったのですが、ハマってしまい解決に時間がかかってしまったので備忘録としてつけておきます。
使用するデータはこちら
d = {
'name': ['tanaka', 'yamada', 'ishii', 'takahashi', 'suzuki', 'yoshida'],
'japanese': [80, 40, 50, 60, 30, 100],
'english': [30, 70, 60, 80, 50, 80],
'math': [50, 60, 80, 40, 70, 20]
}
df = pd.DataFrame(d)
name | japanese | english | math | |
---|---|---|---|---|
0 | tanaka | 80 | 30 | 50 |
1 | yamada | 40 | 70 | 60 |
2 | ishii | 50 | 60 | 80 |
3 | takahashi | 60 | 80 | 40 |
4 | suzuki | 30 | 50 | 70 |
5 | yoshida | 100 | 80 | 20 |
#ハマった箇所
# japanese, englishで50点以上超えた人に語学フラグ0-1を立てる。
df['language'] = 0
df['language'].where((df['japanese'] >= 50) & (df['english'] >= 50), 1, inplace=True)
調べた感じブログやQiitaでは置換や0-1フラグを作る際はwhereメソッドを使用しているケースが多かったので試したところ
name | japanese | english | math | language | |
---|---|---|---|---|---|
0 | tanaka | 80 | 30 | 50 | 1 |
1 | yamada | 40 | 70 | 60 | 1 |
2 | ishii | 50 | 60 | 80 | 0 |
3 | takahashi | 60 | 80 | 40 | 0 |
4 | suzuki | 30 | 50 | 70 | 1 |
5 | yoshida | 100 | 80 | 20 | 0 |
??????????????????
できてないどころかフラグを立ててはいけないところに立てていてびっくりした。
pandasのwhereメソッドのドキュメントを確認したところ
Replace values where the condition is False.(条件がFalseの値を置き換えます。)
なるほどと思ったのですが、比較演算子を逆にして作成すると見た目で誤解を招きそうな気がするので、対応策を考えてみた。
#whereメソッドを使って対処した場合
df['language'].where(~((df['japanese'] >= 50) & (df['english'] >= 50)), 1, inplace=True)
name | japanese | english | math | language | |
---|---|---|---|---|---|
0 | tanaka | 80 | 30 | 50 | 0 |
1 | yamada | 40 | 70 | 60 | 0 |
2 | ishii | 50 | 60 | 80 | 1 |
3 | takahashi | 60 | 80 | 40 | 1 |
4 | suzuki | 30 | 50 | 70 | 0 |
5 | yoshida | 100 | 80 | 20 | 1 |
~(チルダ)を使うことで対策は可能
#maskメソッドを使って対処した場合
df['language'] = 0
df['language'].mask(((df['japanese'] >= 50) & (df['english'] >= 50)), 1, inplace=True)
name | japanese | english | math | language | |
---|---|---|---|---|---|
0 | tanaka | 80 | 30 | 50 | 0 |
1 | yamada | 40 | 70 | 60 | 0 |
2 | ishii | 50 | 60 | 80 | 1 |
3 | takahashi | 60 | 80 | 40 | 1 |
4 | suzuki | 30 | 50 | 70 | 0 |
5 | yoshida | 100 | 80 | 20 | 1 |
結論とりあえずTrue条件で0-1フラグや置換する際はmaskメソッドを使った方がいい気がする。