跳转到主内容
极星编程网:以代码为星,赴技术山海!

Python怎样比较两个DataFrame的数值差异_调用compare方法输出变更明细

compare方法要求pandas≥1.1.0,低版本报AttributeError;需确保两DataFrame索引与列完全对齐,数值类型一致,浮点数需round或改用np.isclose容差比较,NaN需fillna统一处理。 compare方法在pandas 1.1.0+才可用,低版本会报
AttributeError
如果你的pandas低于1.1.0(比如1.0.5或更早),直接调用
df1.compare(df2)
会触发
AttributeError: 'DataFrame' object has no attribute 'compare'
。这不是写法错,是版本硬门槛。 升级是最直接的解法:
pip install --upgrade pandas
升级后验证版本:
import pandas as pd; print(pd.__version__)
确保输出 ≥
1.1.0
。旧项目若不能升级,得改用
df1.eq(df2)
逐元素比对 +
stack()
定位差异,但无法原生输出“变更前/后”结构。 必须保证两个DataFrame行列索引完全对齐,否则
compare
静默丢行/列
compare
默认只对比**索引和列名完全一致**的位置。如果
df1
有索引
[0,1,2]
,
df2
是
[0,1,3]
,那么索引
2
和
3
的行会被自动忽略,不报错也不警告——结果看似“没差异”,实则漏比。 实操前务必检查并统一结构: 立即学习 “ Python免费学习笔记(深入) ”; 用
df1.index.equals(df2.index)
和
df1.columns.equals(df2.columns)
确认布尔返回值为
True
若索引不等,先对齐:
df2 = df2.reindex_like(df1)
(注意:这会引入
NaN
,需结合
keep_shape=True
参数控制) 数值类型也建议一致,比如
int64
vs
float64
可能导致
0 == 0.0
为
True
,但某些场景下你希望视为不同
compare
默认只显示不同值,相同值被压缩;用
keep_equal=True
可保留全量 默认行为是“只汇报差异”,这对查问题很高效,但如果你需要完整对照表(比如生成审计报告),就得显式开启
keep_equal=True
。此时相同值会以双栏形式重复出现(
self
和
other
列值相同)。 Python 3.14.3 微软官方的 Python 扩展,是 VS Code 安装量最高的扩展(209M+)。集成 IntelliSense(通过 Pylance)、调试(通过 Python Debugger)、代码检查、格式化、重构和单元测试等功能。支持 Jupyter Notebook、虚拟环境管理和多 Python 版本切换。 下载 另一个关键参数是
keep_shape
:设为
True
时,即使某行/列全相同,也会保留空结构;设为
False
(默认)则直接剔除整行/列。调试时建议先开
keep_shape=True
,避免误判“没数据=没差异”。 示例调用:
diff = df1.compare(df2, keep_equal=True, keep_shape=True)
返回的
diff
是MultiIndex列的DataFrame,列名为
('colA', 'self')
、
('colA', 'other')
这种二元组,注意后续取列要按层级访问。 数值精度差异(如浮点误差)会导致大量“伪差异”,需预处理 直接比
0.1 + 0.2
和
0.3
会因浮点表示不同而标为差异。pandas的
compare
不做容差判断,它走的是严格相等(
==
语义)。 解决办法分两层: 若数据源可控,在构造
df1
/
df2
时就做round:
df1 = df1.round(10); df2 = df2.round(10)
若需动态容差,不能依赖
compare
,改用
numpy.isclose
逐列计算布尔矩阵,再用
where
提取位置:
import numpy as np; mask = ~np.isclose(df1, df2, atol=1e-8)
注意:
compare
对
NaN
的处理是“
NaN != NaN
”,所以两个
NaN
会被标为差异——如果业务上认为它们相等,得提前用
fillna()
统一替换 真正难的不是调用方法,而是想清楚“什么算差异”:是字节级相等?还是业务意义相等?后者永远需要你在
compare
之外加一层逻辑。

相关文章