使用Pandas检测多份CSV文件数据变更的优化方案求助
用Pandas高效检测CSV数据变更并区分新增/修改记录
直接上最优方案——通过外连接合并两个DataFrame,结合字段对比精准区分「新增记录」「修改记录」和「无变化记录」,完美解决行数不一致的问题,逻辑清晰且易扩展。
步骤1:读取数据并外连接合并
先将两个CSV导入为DataFrame,再以UID为唯一键做外连接,同时通过indicator=True标记每条记录的来源:
import pandas as pd # 读取CSV文件 df1 = pd.read_csv('csv1.csv') df2 = pd.read_csv('csv2.csv') # 外连接合并,给新旧邮箱字段加后缀区分,标记来源 merged_df = pd.merge( df1, df2, on='UID', how='outer', suffixes=('_old', '_new'), indicator=True )
步骤2:标记记录状态
根据_merge字段和邮箱对比结果,给每条记录打上明确的状态标签:
# 定义状态判断逻辑 def get_status(row): if row['_merge'] == 'right_only': return '新增' elif row['_merge'] == 'left_only': return '删除' # 不需要检测删除记录可直接注释此行 elif row['Email_old'] != row['Email_new']: return '邮箱变更' else: return '无变化' # 生成状态列 merged_df['状态'] = merged_df.apply(get_status, axis=1)
步骤3:筛选目标记录
如果只需要关注「新增」和「邮箱变更」的UID,直接筛选即可:
# 筛选变更和新增记录 changed_records = merged_df[merged_df['状态'].isin(['邮箱变更', '新增'])] print(changed_records[['UID', 'Email_old', 'Email_new', '状态']])
示例输出
运行后会得到清晰的结构化结果:
| UID | Email_old | Email_new | 状态 |
|---|---|---|---|
| U02 | u02@email.com | newemail@email.com | 邮箱变更 |
| U04 | u04@email.com | newemail2@email.com | 邮箱变更 |
| U05 | NaN | u05@email.com | 新增 |
| U06 | NaN | u06@email.com | 新增 |
可选:高亮显示到Excel
如果要实现类似你期望的高亮效果,可以输出到Excel并设置条件格式:
# 输出到Excel并高亮变更/新增行 with pd.ExcelWriter('变更记录.xlsx') as writer: merged_df.to_excel(writer, sheet_name='所有记录', index=False) worksheet = writer.sheets['所有记录'] # 高亮邮箱变更行(黄色) worksheet.conditional_format('A1:Z1000', {'type': 'formula', 'criteria': '=$E1="邮箱变更"', 'format': {'bg_color': '#FFFF00'}}) # 高亮新增行(绿色) worksheet.conditional_format('A1:Z1000', {'type': 'formula', 'criteria': '=$E1="新增"', 'format': {'bg_color': '#00FF00'}})
方案优势
- 完全适配行数不一致的场景,规避
pandas.compare的局限性 - 明确区分四种记录状态,逻辑清晰无歧义
- 代码简洁易维护,后续扩展其他字段对比只需修改判断逻辑即可
内容的提问来源于stack exchange,提问作者JS0NBOURNE
相关产品推荐
相关产品推荐

