名字かぶりを検出・修正するプログラムをfor無しで組みたい
解決したいこと
表1のような名簿がある。これを下記ルールのもとで表2のかたちにしたい。
実装はできたものの、for文で2回ループさせてしまっているので、何か上手い手が無いかご教示いただきたい。
表1 名簿
名前 | 旧姓 |
---|---|
田中 太郎 | |
佐藤 次郎 | |
鈴木 三郎 | 山田 三郎 |
田中 五郎 | |
佐藤 次子 |
<適用するルール>
・旧姓がある場合は、旧姓を名前として扱う(表1の場合、鈴木三郎さんは山田三郎さんとして扱う)
・名字が重なっている場合は、名前の一文字目を()書きでくっつける
・名字と名前の一文字目が同じ場合、スペースナ無しのフルネームで書く
表2 ルール適用後の名簿
名前 | NAME |
---|---|
田中 太郎 | 田中(太) |
佐藤 次郎 | 佐藤次郎 |
鈴木 三郎 | 鈴木 |
田中 五郎 | 田中(五) |
佐藤 次子 | 佐藤次子 |
該当するソースコード(表2は生成できる)
import pandas as pd
df = pd.DataFrame(
data=[{'名前': "田中 太郎", '旧姓': None,},
{'名前': "佐藤 次郎", '旧姓': None,},
{'名前': "鈴木 三郎", '旧姓': "山田 三郎",},
{'名前': "田中 五郎", '旧姓': None,},
{'名前': "佐藤 次子", '旧姓': None,}])
#名字と名前を分離
df_name = df["名前"].str.split(" ",expand=True)
df_name.update(df["旧姓"].str.split(" ",expand=True))
#空列の確保
df_name["NAME_temp"]=""
df_name["NAME"]=""
#sum関数で名字かぶりを探し、重なりがあれば名字+名前一文字目を出力
for i in range(0,len(df)):
name_kaburi = (df_name[0]==df_name.at[i,0]).sum()
if name_kaburi >=2:
df_name.at[i,"NAME_temp"]=df_name.at[i,0]+"("+df_name.at[i,1][0]+")"
else :
df_name.at[i,"NAME_temp"]=df_name.at[i,0]
#sum関数で名字+名前一文字目かぶりを探し、重なりがあればフルネームで出力
for i in range(0,len(df)):
all_kaburi = (df_name["NAME_temp"]==df_name.at[i,"NAME_temp"]).sum()
if all_kaburi >=2:
df_name.at[i,"NAME"]=df_name.at[i,0]+df_name.at[i,1]
else:
df_name.at[i,"NAME"]=df_name.at[i,"NAME_temp"]
#不要な行とカラム名を修正
df_name=df_name.rename(columns={0:"名前"})
df_name=df_name[["名前","NAME"]]
問題点、疑問点
・for文を2ループ回す必要はないのではないか? そもそもあまりfor文は使わないほうがいいとも聞く。
・わざわざNAME_tempを作るのが無駄に感じる
・dataframeを処理する時はtolist()を使ったほうが早いと聞いたが、実際のデータは数百行レベル。
そういう場合でもforは避けたほうが良いのか?
などなどありますが、上記よりもスッキリとプログラムを纏める方法があればぜひ伺いたく・・・。
0