对比同结构不同长度DataFrame并高亮差异时遇报错的技术求助
解决DataFrame对比高亮差异的问题
问题根源
- 报错
Can only compare identically-labeled DataFrame objects:df.compare()要求两个DataFrame的索引完全匹配,哪怕列名一致,只要长度不同、索引标签不一致就会触发。你代码里用的ignore_index=True不是compare的参数,完全没生效。 - 报错
'function' object has no attribute 'style':equal()方法返回的是布尔值(True/False),不是DataFrame对象,自然没有style属性,属于用错方法。
正确实现步骤
1. 对齐两个DataFrame的索引
先把两个DF的索引重置为默认连续整数,解决长度不同导致的索引不匹配问题:
# 重置索引并丢弃原索引 df = df.reset_index(drop=True) df2 = df2.reset_index(drop=True)
2. 生成对比结果与差异掩码
用compare()生成包含差异的结果集,再创建标记差异位置的掩码:
# 生成对比结果:保留所有行/列,同时显示相同值和差异值 df_compare = df.compare(df2, keep_shape=True, keep_equal=True) # 创建单元格级掩码:有差异的位置标记为1,无差异为0 df_mask = df_compare.notnull().astype(int)
3. 编写高亮函数并应用
修正原代码的拼写错误,将样式正确应用到对比结果上:
def apply_colour(x): # 为有差异的单元格设置浅蓝色背景 colors = {1: 'background-color: lightblue', 0: ''} return df_mask.applymap(lambda val: colors.get(val, '')) # 应用样式并生成可显示的结果 styled_df = df_compare.style.apply(apply_colour, axis=None) styled_df
完整可运行示例
import pandas as pd # 模拟测试数据 data1 = { '地址': ['北京市朝阳区', '上海市黄浦区', '广州市天河区'], '参考编号': ['REF001', 'REF002', 'REF003'], '名称': ['A公司', 'B公司', 'C公司'] } data2 = { '地址': ['北京市朝阳区', '上海市静安区', '广州市天河区', '深圳市南山区'], '参考编号': ['REF001', 'REF002', 'REF004', 'REF005'], '名称': ['A公司', 'B集团', 'C公司', 'D公司'] } df = pd.DataFrame(data1) df2 = pd.DataFrame(data2) # 对齐索引 df = df.reset_index(drop=True) df2 = df2.reset_index(drop=True) # 生成对比结果和掩码 df_compare = df.compare(df2, keep_shape=True, keep_equal=True) df_mask = df_compare.notnull().astype(int) # 高亮函数 def apply_colour(x): colors = {1: 'background-color: lightblue', 0: ''} return df_mask.applymap(lambda val: colors.get(val, '')) # 应用样式并显示 styled_result = df_compare.style.apply(apply_colour, axis=None) styled_result
关键说明
reset_index(drop=True)是解决第一个报错的核心:统一两个DF的索引为连续整数,消除索引不匹配的问题。compare()参数说明:keep_shape=True保留所有行和列,避免因长度不同丢失数据;keep_equal=True同时展示相同值和差异值,默认仅显示差异。- 掩码维度可选:如果需要整行高亮,可将
df_mask改为df_compare.notnull().any(axis=1).astype(int),对应调整样式逻辑即可。
内容的提问来源于stack exchange,提问作者Laura Wilkins
相关产品推荐
相关产品推荐

