1. ホーム
  2. python

[解決済み] Pandas - pandasのケースwhenとdefault

2022-03-03 05:01:42

質問

Pythonで以下のようなcase文があります。

pd_df['difficulty'] = 'Unknown'
pd_df['difficulty'][(pd_df['Time']<30) & (pd_df['Time']>0)] = 'Easy'
pd_df['difficulty'][(pd_df['Time']>=30) & (pd_df['Time']<=60)] = 'Meduim'
pd_df['difficulty'][pd_df['Time']>60] = 'Hard'

しかし、このコードを実行すると、エラーが発生します。

A value is trying to be set on a copy of a slice from a DataFrame

解決方法は?

オプション1
パフォーマンスのために、ネストされた np.where という条件を設定します。条件については、単に pd.Series.between を指定すると、それに応じてデフォルト値が挿入されます。

pd_df['difficulty'] = np.where(
     pd_df['Time'].between(0, 30, inclusive=False), 
    'Easy', 
     np.where(
        pd_df['Time'].between(0, 30, inclusive=False), 'Medium', 'Unknown'
     )
)


オプション2
同様に np.select これによって、条件を追加する余地が広がります。

pd_df['difficulty'] = np.select(
    [
        pd_df['Time'].between(0, 30, inclusive=False), 
        pd_df['Time'].between(30, 60, inclusive=True)
    ], 
    [
        'Easy', 
        'Medium'
    ], 
    default='Unknown'
)


オプション3
もう一つのパフォーマンス的な解決策としては loc :

pd_df['difficulty'] = 'Unknown'
pd_df.loc[pd_df['Time'].between(0, 30, inclusive=False), 'difficulty'] = 'Easy'
pd_df.loc[pd_df['Time'].between(30, 60, inclusive=True), 'difficulty'] = 'Medium'