如何对比两个Pandas DataFrame,识别缺失行与缺失单元格?
Pandas DataFrame差异对比:识别缺失行/单元格+Excel高亮导出
一、识别缺失行与单元格差异
要解决这个问题,需先对齐两个DataFrame的行结构,再逐个单元格对比,同时区分缺失行和**单元格值差异(含NaN缺失)**两种场景。
1. 识别缺失行
通过合并两个DataFrame并标记行来源,快速定位仅在其中一个DataFrame存在的行:
import pandas as pd import numpy as np x = [[0, 1, 2, 3],[4, 5, 6, 7],[8, 9, 10, 11],[12, 13, 14, 15]] y = [[np.nan, 1, 2, 3],[4, 5, 6, np.nan],[12, 13, 14, 15]] df1 = pd.DataFrame(x) df2 = pd.DataFrame(y) # 合并并标记每行所属的DataFrame merged = pd.concat([df1, df2], keys=['df1', 'df2'], axis=0).reset_index(level=0) # 找出df2缺失的行(仅在df1存在) df1_unique = merged[merged['level_0'] == 'df1'] df2_missing_rows = df1_unique[~df1_unique.isin(df2.to_dict('list')).all(axis=1)] # 找出df1缺失的行(仅在df2存在) df2_unique = merged[merged['level_0'] == 'df2'] df1_missing_rows = df2_unique[~df2_unique.isin(df1.to_dict('list')).all(axis=1)] print("df2缺失的行:") print(df2_missing_rows) print("\ndf1缺失的行:") print(df1_missing_rows)
2. 识别单元格差异(含NaN)
由于NaN无法直接用==判断,需同时对比值是否相等、是否存在NaN差异:
# 生成差异矩阵:值不等 或 一方是NaN另一方不是 diff_matrix = (df1 != df2) | (df1.isna() != df2.isna()) # 提取所有差异单元格的位置 diff_cells = diff_matrix.stack()[diff_matrix.stack()].reset_index() diff_cells.columns = ['行索引', '列索引', '是否差异'] print("\n差异单元格位置:") print(diff_cells)
二、差异高亮并导出至Excel
利用Pandas的Styler工具给差异单元格、缺失行添加背景色,再导出到Excel:
def highlight_cell_diff(row, df_compare): # 标记当前行与对比行的单元格差异 mask = (row != df_compare.loc[row.name]) | (row.isna() != df_compare.loc[row.name].isna()) return ['background-color: #ffcccc' if v else '' for v in mask] def highlight_missing_row(row, missing_idx): # 标记缺失行(仅在当前DataFrame存在的行) return ['background-color: #ffff99' if row.name in missing_idx else '' for _ in row] # 高亮单元格差异 styled_df = df1.style.apply(highlight_cell_diff, df_compare=df2, axis=1) # 高亮df1独有的行(df2缺失) df1_missing_idx = df1.index.difference(df2.index) styled_df = styled_df.apply(highlight_missing_row, missing_idx=df1_missing_idx, axis=1) # 导出到Excel styled_df.to_excel('df_diff_result.xlsx', engine='openpyxl', index=True)
补充说明
- 如果行是按索引对应而非值匹配,直接用索引差集(
df1.index.difference(df2.index))判断缺失行更高效。 - 高亮颜色可自行调整:
#ffcccc为浅红(标记单元格差异),#ffff99为浅黄(标记缺失行)。
内容的提问来源于stack exchange,提问作者Spencer Ekstrom
相关产品推荐
相关产品推荐

