如何比较长度不同的两个pandas DataFrame并返回差异单元格
报错原因
pandas 内置的DataFrame.compare()方法默认要求两个待比对对象的行索引、列索引完全一致才能执行比对。示例中df有3行数据,df2只有2行数据,二者行索引长度不匹配,因此触发ValueError: Can only compare identically-labeled Dataframe objects报错。
修正方案
先对齐两个DataFrame的行索引,再执行差异比对,行数不足的DataFrame缺失的行会自动标记为差异。完整可运行代码如下:
import pandas as pd # 测试数据 data = [('11','12','13'), ('21','22','23'), ('31','32','33')] df = pd.DataFrame(data, columns=('col_1', 'col_2', 'col_3')) data2 = [('11','12','13'), ('21','22','23')] df2 = pd.DataFrame(data2, columns=('col_1', 'col_2', 'col_3')) def diff_dataframe(df1, df2, missing_mark="__缺失行__"): # 重置索引,排除原有自定义索引的干扰 df1 = df1.reset_index(drop=True) df2 = df2.reset_index(drop=True) # 对齐两个DataFrame的行范围,取最大行数作为统一索引 max_row = max(len(df1), len(df2)) full_index = list(range(max_row)) df1_align = df1.reindex(full_index, fill_value=missing_mark) df2_align = df2.reindex(full_index, fill_value=missing_mark) # 生成差异掩码:值不相等的位置标记为1 diff_mask = (df1_align != df2_align).astype("int") # 生成保留所有值的比对结果表 df_compare = df1_align.compare(df2_align, keep_shape=True, keep_equal=True) # 差异单元格高亮样式 def set_color(_): color_conf = {1: "background-color: lightblue", 0: "background-color: white"} return diff_mask.applymap(lambda v: color_conf[v]) return df_compare.style.apply(set_color, axis=None) # 调用函数获取带高亮的比对结果 diff_result = diff_dataframe(df, df2) diff_result
逻辑说明
- 比对前先重置两个DataFrame的行索引,避免自定义索引值不一致导致的对齐失败
- 以两个DataFrame的最大行数为基准做重索引,行数更少的DataFrame缺失部分用特殊标记填充,会被自动识别为差异
- 共有行逐单元格比对值,值不一致的单元格会标记为浅蓝色高亮
- 比对结果中会同时展示两个DataFrame在对应位置的取值,方便直接核对差异内容
内容的提问来源于stack exchange,提问作者MFaragal
相关产品推荐
相关产品推荐

