広告/統計/アニメ/映画 等に関するブログ

広告/統計/アニメ/映画 等に関するブログ

Pandasで文字列に対してcase_whenをしたいときの注意箇所

pandas でSQLのcase_whenのように、特定の列の条件に応じて新しく分類を作りたい場合がある。

様々な選択肢があるが、シンプルなのはこのサイトのように関数を作って列に適用させる手法だろう。

qiita.com

数値の列であれば参考サイトの通りに行えば問題ないが、文字列の場合は注意が必要だ。

テストデータの準備

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'」というエラーでググると、丁寧に説明しているページがあった

stackoverflow.com

df["商品名"]の各要素の型は「str」なのだ

type(df["商品名"][1])
str

解決策

では、「str」型の文字列に対して「~を含む」などの処理をどうするかというと、こちらのサイトに紹介がある。

note.nkmk.me

ということで、関数は以下のように書き直して実行すれば良い。

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データフレームに新しいカテゴリ分類を追加することができた。