データの前処理では、何らかのルールに基づいてデータを置換したい場面が多々あります。たとえば、次のようなケースです。
- ある値以上のデータは外れ値として扱い、上限値で置換したい。
- コード番号(
01
、13
など)で表現されているデータを、人間が見て意味のわかる名称("北海道"
、"東京"
)で置換したい。
pandasで特定のデータを置換するには、たとえば次のようなメソッドがあります。
メソッド | 説明 | 学べる場所 |
---|---|---|
mask(条件, 置換後の値) | 指定した条件に一致するデータを置換する | 本問題 |
where(条件, 置換後の値) | 指定した条件に一致しないデータを置換する | 本問題 |
map(辞書) | 辞書のキーと値の対応付けにしたがってデータを置換する | 次の問題 |
apply(関数) | すべての行に対して、指定した関数を適用する。より複雑なルールで値を置換したいときに便利 | 次のクエスト「列や行に関数を適用しよう」 |
mask()による置換
mask()
を使うと、指定した条件に一致するデータを置換後の値
で置換した結果が得られます。
# 指定した条件に一致するデータを置換
df[列名].mask(条件, 置換後の値)
具体的な例を見てみましょう。
次のような、顧客ごとの支払い総額のデータがあるとします。
顧客番号 | 支払い総額 | 顧客区分 | |
---|---|---|---|
0 | user1 | 8000 | 普通顧客 |
1 | user2 | 32000 | 普通顧客 |
2 | user3 | 150000 | 普通顧客 |
3 | user4 | 0 | 普通顧客 |
列顧客区分
の値はすべて"普通顧客"
ですが、支払い総額が10万円以上の顧客に "優良顧客"
という区分を割り当ててみましょう。次のように書くことで、「支払い総額
が10万円以上のデータの顧客区分
を "優良顧客"
に置換した結果」を取得できます。
df["顧客区分"].mask(df["支払い総額"] >= 100000, "優良顧客")
0 普通顧客
1 普通顧客
2 優良顧客
3 普通顧客
Name: 顧客区分, dtype: object
3行目のデータ(支払い総額
が15万円)の 顧客区分
だけが"優良顧客"
に置換され、他のデータはそのままであることがわかります
mask()
を実行しただけでは元のdf
は変更されないので、置換した結果を反映したい場合は次のように列を更新します。
df=という形にしない。df[]=という形にして、dfの変更されている範囲を決めて記載すること。
df["顧客区分"] = df["顧客区分"].mask(df["支払い総額"]
なお、置換後の値が未指定の場合は、条件に一致するデータがNaNになります。
df["顧客区分"].mask(df["支払い総額"] >= 100000)
0 普通顧客
1 普通顧客
2 NaN
3 普通顧客
Name: 顧客区分, dtype: object
where()による置換
mask()
と似た機能のメソッドにwhere()
があります。mask()
は指定した条件に一致するデータを置換しますが、where()
は指定した条件に 一致しない データを置換後の値
で置換します。
# 指定した条件に一致しないデータを置換
df[列名].where(条件, 置換後の値)
先ほどの例と同様「支払い総額
が10万円以上のデータの顧客区分
を、"優良顧客"
にする」場合、次のように書きます。
df["顧客区分"].where(df["支払い総額"] < 100000, "優良顧客")
mask()
では条件の部分に「支払い総額が10万円以上」を指定しましたが、where()
では「支払い総額が10万円未満」になっている点に注意してください。
コメント