#概要
「データに含まれる文字の一括変換方法」
https://qiita.com/wellwell3176/questions/1345ab14964d2a050b5a
上記質問への回答を元にプログラムを作成した。
質問ページに貼ると長くなりすぎたので分割のために投稿。
#仕様
表1の生データに対し、表2に在る変換表を用いて記号を分離・変換して新たな列に格納する
今回のデータでは表2の変換表が小さいが、実際のデータでは記号が30種類、列ラベルが10種類ほどあるので、
「1枚のエクセルファイルで変換表をなるべくまとめたい」という希望があった。
※表2くらいのサイズならエクセルファイルのタブごとに「個人予想の変換表」「新聞予想の変換表」と作って管理したほうが絶対楽
表1 生データ
No. | 馬名 |
---|---|
1 | コシヒカリ○③ |
2 | ササニシキ◎ |
3 | ヨモギダンゴ✕② |
4 | タナカタロウ① |
表2 変換表
個人予想 | 新聞予想 | |
---|---|---|
① | 1番 | |
② | 2番 | |
③ | 3番 | |
◎ | 本命 | |
○ | 対抗 | |
✕ | 大穴 |
#実装したプログラム
完成品
import pandas as pd
#質問回答で提示いただいた汎用プログラムを流用
def tagging(df, column, trdict): #もとのDataFrame, 分類に使用するカラム, 分類用の辞書
for key, d in trdict.items():
#データフレームの1st key(個人予想、新聞予想)ごとに処理を行う。
df_ = df[column].str.extract(f'({"|".join(d.keys())})')
for k, v in d.items():
df_ = df_.replace(k, v)
#2nd key(◎✕など)で抽出して新列を作った後、2nd key と valueを変換
df[column] = df[column].str.replace(k, "")
df[key] = df_.fillna("")
#抽出元の列から2nd keyを削除
return df
df = pd.DataFrame( #サンプルデータを作成。実際にはエクセル読み込み
data=[{
'No.': 1,
'horse': 'コシヒカリ○③',
}, {
'No.': 2,
'horse': 'ササニシキ◎',
}, {
'No.': 3,
'horse': 'ヨモギダンゴ✕②',
}, {
'No.': 4,
'horse': 'タナカタロウ①',
}])
dict_raw = pd.read_excel("hogehoge.xlsx",index_col=0)
#hogehoge.xlsxは表2のエクセルデータに等しい
dict_process=dict_raw.to_dict(orient='dict')
#to_dictで辞書形式に変換
list_key=list(dict_process.keys())
#for文で使うので、keyの中身をリスト化(辞書のままだと順序を持たないのでfor文の対象として選べない)
dict_comp=dict() #update()を使うので、完成品を空の辞書として先に生成
#辞書から値を持たないkeyを削除(今回の場合、"個人予想":"◎"にはnanが格納されていて邪魔)
for i in list_key:
output_dict = dict(filter(lambda item: item[1] is not np.nan, d3[i].items()))
dict_comp.update({i:output_dict})
tagging(df,"horse",dict_comp)
<出力結果>
No. horse 個人予想 新聞予想
0 1 コシヒカリ 3番 対抗
1 2 ササニシキ 本命
2 3 ヨモギダンゴ 2番 大穴
3 4 タナカタロウ 1番
#参考リンク
辞書フィルタリングの参考元:
https://tombomemo.com/python-dict-filter/