如何删除DataFrame中old与new无差异的行?附数据对比需求
对比两个DataFrame并保留高亮差异行的解决方案
测试数据示例
先贴出测试用的新旧DataFrame:
import pandas as pd # 旧数据 old_df = pd.DataFrame({ 'ID': [1, 2, 3, 4], 'Name': ['Alice', 'Bob', 'Charlie', 'David'], 'Age': [25, 30, 35, 40], 'City': ['New York', 'London', 'Paris', 'Tokyo'] }) # 新数据 new_df = pd.DataFrame({ 'ID': [1, 2, 3, 4], 'Name': ['Alice', 'Bob', 'Charlie', 'Dave'], 'Age': [25, 32, 35, 40], 'City': ['New York', 'London', 'Berlin', 'Tokyo'] })
完整实现代码
直接用这段代码就能完成需求,自动过滤无差异行、高亮差异并保存:
import pandas as pd from pandas.io.formats.style import Styler def highlight_diff(data, old_data, new_data): # 生成空样式表,给差异单元格加浅红背景 style_table = pd.DataFrame('', index=data.index, columns=data.columns) for row_idx in data.index: for col in data.columns: # 拆分双层列名,拿到原数据列名 _, original_col = col if old_data.loc[row_idx, original_col] != new_data.loc[row_idx, original_col]: style_table.loc[row_idx, col] = 'background-color: #ffcccc' return style_table # 先检查结构一致性,避免对比出错 if set(old_df.columns) != set(new_df.columns): raise ValueError("两个DataFrame列名不匹配,请先统一结构") if not old_df.index.equals(new_df.index): raise ValueError("两个DataFrame行索引不对应,请确认行顺序一致") # 只保留存在差异的行 has_diff = old_df.ne(new_df).any(axis=1) # 合并新旧数据为双层列结构,方便对比查看 diff_rows = pd.concat([old_df[has_diff], new_df[has_diff]], keys=['旧数据', '新数据'], axis=1) # 给差异单元格添加高亮样式 styled_result = diff_rows.style.apply(highlight_diff, old_data=old_df[has_diff], new_data=new_df[has_diff], axis=None) # 保存到Excel文件 with pd.ExcelWriter('差异对比结果.xlsx') as writer: styled_result.to_excel(writer, sheet_name='差异数据')
代码说明
- 结构校验:先核对列名和索引,防止因结构不一致导致对比混乱(比如列数不同、行顺序不对应)。
- 过滤无差异行:用
ne()逐单元格对比新旧值,any(axis=1)判断每行是否存在差异,直接过滤掉完全相同的行(比如测试数据里的ID=1行)。 - 高亮差异:自定义函数遍历每个单元格,只要新旧值不同,就给单元格添加浅红色背景,直观展示差异位置。
- 保存结果:直接将带样式的对比结果存入Excel,打开即可看到高亮的差异,无需手动二次处理。
期望的Excel结果样式
生成的Excel仅保留存在差异的行,差异单元格会显示浅红色背景,示例如下:
| 旧数据 | 新数据 | |||||||
|---|---|---|---|---|---|---|---|---|
| ID | Name | Age | City | ID | Name | Age | City | |
| 2 | 2 | Bob | 30(红底) | London | 2 | Bob | 32(红底) | London |
| 3 | 3 | Charlie | 35 | Paris(红底) | 3 | Charlie | 35 | Berlin(红底) |
| 4 | 4 | David(红底) | 40 | Tokyo | 4 | Dave(红底) | 40 | Tokyo |
内容的提问来源于stack exchange,提问作者TOMATOKILLER
相关产品推荐
相关产品推荐

