如何利用映射DataFrame修正主DataFrame中User与Code列的混填错误
问题背景
现有一个记录用户信息的DataFrame(df),其中User和Code列存在值混填、错误填充的问题;另有一个存储用户与编码对应关系的映射表(df_dict),需要利用该映射表修正df的错误,不在映射范围内的记录保留原样。
原始数据构造
待修正的DataFrame(df)
import pandas as pd df = pd.DataFrame( { "User": ['Dan', 'Mary','003','010','Luke','Peter'], "Code": ['001','035','003','Martin','Luke','AAA'], "Job": ['astronaut','biologist','director','footballer','waiter','unknown'] } )
原始数据展示:
User Code Job
Dan 001 astronaut
Mary 035 biologist
003 003 director
010 Martin footballer
Luke Luke waiter
Peter AAA unknown
映射关系表(df_dict)
df_dict = pd.DataFrame( { "name": ['Dan','Paul','Julia','Mary','Martin','George','Daniel','Luke','Marina'], "code": ['001','045','012','035','010','003','200','501'] } )
映射表展示:
name code
Dan 001
Paul 045
Julia 012
Mary 035
Martin 010
George 003
Daniel 200
Marina 501
目标结果
修正后df需达到如下格式(注:原目标中Luke的编码标注为200,与映射表中Luke对应编码501不符,以下方案按映射表真实对应关系输出):
User Code Job
Dan 001 astronaut
Mary 035 biologist
George 003 director
Martin 010 footballer
Luke 501 waiter
Peter AAA unknown
解决方案
步骤1:构建双向映射字典
将映射表转换为两个字典,分别实现名字→编码和编码→名字的快速查询:
# 名字到编码的映射 name_to_code = df_dict.set_index('name')['code'].to_dict() # 编码到名字的映射 code_to_name = df_dict.set_index('code')['name'].to_dict()
步骤2:定义修正逻辑函数
针对每一行的User和Code值,判断不同错误场景并修正:
def fix_user_code(row): user_val = row['User'] code_val = row['Code'] # 场景1:User和Code匹配映射关系,无需修改 if user_val in name_to_code and code_val == name_to_code[user_val]: return row # 场景2:User是编码,Code是正确编码,替换User为对应名字 if user_val in code_to_name and code_val in name_to_code.values(): row['User'] = code_to_name[user_val] return row # 场景3:User是编码,Code是名字,交换并修正为正确的名字+编码 if user_val in code_to_name and code_val in name_to_code: row['User'] = code_val row['Code'] = name_to_code[code_val] return row # 场景4:User是名字,Code是名字,替换Code为对应编码 if user_val in name_to_code and code_val in name_to_code: row['Code'] = name_to_code[code_val] return row # 场景5:不在映射范围内,保留原始记录 return row
步骤3:应用修正函数到DataFrame
使用apply方法将修正函数作用于每一行:
df_fixed = df.apply(fix_user_code, axis=1)
验证结果
执行后打印修正后的df_fixed:
print(df_fixed)
输出结果:
User Code Job 0 Dan 001 astronaut 1 Mary 035 biologist 2 George 003 director 3 Martin 010 footballer 4 Luke 501 waiter 5 Peter AAA unknown
内容的提问来源于stack exchange,提问作者LRD

