dataframeから複数列の文字列を参照して、その内容に応じて新たな列にデータを入力する


前回同様、質問を書くために色々と試していたら上手く行ったので備忘録がてら投稿。

データ量が大きい場合にはもっと上手い方法がありそうな気もする……。

主題

表1のデータに対し、表2を参照してデータを追加し、表3のようにしたい

表1 生データ

時間 種類
ごはん
パン
パン
パン
ごはん

実際の生データは左にIDが入っていて、行ごとに固有のデータ。
データ量は10万行ほど。

表2 参照表

時間 種類 内容
ごはん 茶漬け
パン トースト
ごはん ふりかけ
パン トースト
ごはん ごはん
パン 食パン

実際の参照表はそれなりに大きい(100行くらい)。

表3 作りたいデータ

時間 種類 内容
ごはん 茶漬け
パン トースト
パン トースト
パン 食パン
ごはん 茶漬け

解法① 参照する2列を結合して1列にした後、表2から辞書ファイルを作って変換

import pandas as pd
#df=表1に該当する生データ
df = pd.DataFrame(
    data=[{'時間': "朝", '分類': "ごはん"},
          {'時間': "朝", '分類': "パン"},
          {'時間': "朝", '分類': "パン"},
          {'時間': "夜", '分類': "パン"},
          {'時間': "朝", '分類': "ごはん"}])

#df_replace=表2に該当するデータ。実際にはエクセル管理しておき、read_excelで取り出す。
df_replace =pd.DataFrame(
    data=[{'時間': "朝", '分類': "ごはん","内容":"茶漬け"},
          {'時間': "朝", '分類': "パン","内容":"トースト"},
          {'時間': "夜", '分類': "ごはん","内容":"ごはん"},
          {'時間': "夜", '分類': "パン","内容":"食パン"}])

df["内容"]=df["時間"]+df["分類"]
df_replace["変換詞"] = df_replace["時間"]+df_replace["分類"]
 #今回のケースの場合、文字列2列の組合せたものを比較するため、まず比較対象列を結合してしまう。

dict_replace = dict(zip(df_replace["変換詞"], df_replace['内容']))
 #読み込んだエクセルファイル(表2)を用いて、変換前文字列-変換後文字列を辞書ファイルに作成する

df["内容"]=df["内容"].replace(dict_replace)
 #replaceで一括変換を掛ける(データ量が大きい場合にはtolist()でリスト化してから処理したほうが多分高速)

解法② 表2が小さければ条件式を全部書いてしまうのもありか?

import pandas as pd
#dataframeの作成
df = pd.DataFrame(
    data=[{'時間': "朝", '分類': "ごはん"},
          {'時間': "朝", '分類': "パン"},
          {'時間': "朝", '分類': "パン"},
          {'時間': "夜", '分類': "パン"},
          {'時間': "朝", '分類': "ごはん"}])

#条件ごとに.locを使って内容に値を代入
df.loc[(df["時間"] =="朝")&(df["分類"]=="パン"),"内容"]="トースト"
df.loc[(df["時間"] =="朝")&(df["分類"]=="ごはん"),"内容"]="茶漬け"
df.loc[(df["時間"] =="夜")&(df["分類"]=="パン"),"内容"]="食パン"

.locを使って条件式を全部書いてしまえばなんとかなるが、今回は表2が大きいのでこれでは面倒臭すぎて失敗。