You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自定义DataFrame.compare函数实现浮点型数据容差比较

Pandas中让DataFrame.compare忽略浮点微小差异的实现方法

原生pandas.DataFrame.compare可以高效对比结构一致的DataFrame,值相同的单元格会返回NaN,能快速定位差异。但处理浮点型数据时,哪怕是极小的精度差异(比如1.11和1.1099999999),都会被判定为不同,导致输出里全是差异,无法快速找到真正的大差异。

示例对比

整数对比的正常表现

import pandas as pd

df1 = pd.DataFrame({'A': [10, 11], 'B': [20, 22]})
df2 = pd.DataFrame({'A': [10, 11], 'B': [20, 23]})
print(df1.compare(df2))

输出:

A        B     
  self other self other
0  NaN   NaN  NaN   NaN
1  NaN   NaN   22    23

浮点对比的问题场景

df3 = pd.DataFrame({'A': [1.11, 1.12], 'B': [1.21, 1.22]})
df4 = pd.DataFrame({'A': [1.1099, 1.1199], 'B': [1.2099, 1.2001]})
print(df3.compare(df4))

原生输出会把所有浮点行标记为差异,但我们期望只保留真正超出容忍度的差异(比如示例中第1行的B列),其余显示NaN:

A        B     
  self other self other
0  NaN   NaN  NaN   NaN
1  NaN   NaN  1.22 1.2001

解决方案:自定义带容忍度的对比函数

不需要重写__ge__、__le__这类魔法方法,我们可以基于np.isclose自定义对比逻辑,生成和原生compare结构一致的输出:

import pandas as pd
import numpy as np

def compare_with_tolerance(df_self, df_other, rtol=1e-05, atol=1e-08):
    # 生成近似相等的掩码,通过rtol和atol控制容忍度
    mask = np.isclose(df_self, df_other, rtol=rtol, atol=atol)
    # 提取self中不相等的值,相等位置设为NaN
    self_diff = df_self.where(~mask)
    # 提取other中不相等的值,相等位置设为NaN
    other_diff = df_other.where(~mask)
    # 组合成多级列结构,和原生compare对齐
    result = pd.concat([self_diff, other_diff], axis=1, keys=['self', 'other'])
    # 调整列顺序,匹配原生的「列名 -> self/other」层级
    result = result.swaplevel(axis=1).sort_index(axis=1)
    return result

# 测试:设置宽松的容忍度,忽略微小浮点差异
df3 = pd.DataFrame({'A': [1.11, 1.12], 'B': [1.21, 1.22]})
df4 = pd.DataFrame({'A': [1.1099, 1.1199], 'B': [1.2099, 1.2001]})
print(compare_with_tolerance(df3, df4, rtol=1e-3))

逻辑说明

  • np.isclose通过**相对误差(rtol)和绝对误差(atol)**判断浮点数是否近似相等,默认参数适合大多数场景,可根据业务需求调整阈值。
  • 通过掩码筛选出真正不相等的值,相等位置填充NaN,再组合成和原生compare完全一致的多级列结构。
  • 交换列层级顺序后,输出格式和原生compare完全对齐,无需额外适配。

内容的提问来源于stack exchange,提问作者Gary

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 06:15:04