pandas でSQLのcase_whenのように、特定の列の条件に応じて新しく分類を作りたい場合がある。
様々な選択肢があるが、シンプルなのはこのサイトのように関数を作って列に適用させる手法だろう。
数値の列であれば参考サイトの通りに行えば問題ないが、文字列の場合は注意が必要だ。
テストデータの準備
import numpy as np import pandas as pd
df = pd.DataFrame({ "商品名":["オレンジ","アップル","はくさい","れんこん","サバ"], "売上":[100,120,80,40,90] }) display(df)
商品名 | 売上 | |
---|---|---|
0 | オレンジ | 100 |
1 | アップル | 120 |
2 | はくさい | 80 |
3 | れんこん | 40 |
4 | サバ | 90 |
このデータフレームに新しく「野菜」「魚」「果物」などの分類列を加えたいものとする。
str.containsではエラーになる
文字列の条件といえば、str.containsである。
商品名にオレンジを含むかどうかであれば以下のように記述すれば良い
df["商品名"].str.contains("オレンジ")
0 True 1 False 2 False 3 False 4 False Name: 商品名, dtype: bool
だが、ここで先程のサイトのように関数にするとエラーになる
def func_case_when_kubun_1(x): if x.str.contains("オレンジ"): return "果物" elif x.str.contains("アップル"): return "果物作" elif x.str.contains("はくさい"): return "野菜" elif x.str.contains("れんこん"): return "野菜" elif x.str.contains("サバ"): return "魚" else: return "その他" df["商品名"].apply(func_case_when_kubun_1)
AttributeError: 'str' object has no attribute 'str'
エラーの理由
「 'str' object has no attribute 'str'」というエラーでググると、丁寧に説明しているページがあった
df["商品名"]の各要素の型は「str」なのだ
type(df["商品名"][1])
str
解決策
では、「str」型の文字列に対して「~を含む」などの処理をどうするかというと、こちらのサイトに紹介がある。
ということで、関数は以下のように書き直して実行すれば良い。
def func_case_when_kubun_2(x): if "オレンジ" in x: return "果物" elif "アップル" in x: return "果物作" elif "はくさい" in x: return "野菜" elif "れんこん" in x: return "野菜" elif "サバ" in x: return "魚" else: return "その他" df["商品名"].apply(func_case_when_kubun_2)
0 果物 1 果物作 2 野菜 3 野菜 4 魚 Name: 商品名, dtype: object
元のデータフレームに列を追加したいので以下のように插入する
df["分類"] = df["商品名"].apply(func_case_when_kubun_2) display(df)
商品名 | 売上 | 分類 | |
---|---|---|---|
0 | オレンジ | 100 | 果物 |
1 | アップル | 120 | 果物作 |
2 | はくさい | 80 | 野菜 |
3 | れんこん | 40 | 野菜 |
4 | サバ | 90 | 魚 |
これで、文字列条件を使ってpandasデータフレームに新しいカテゴリ分類を追加することができた。