浮点数运算与比较异常:Pandas数据对比问题排查与修复
问题背景
现有Pandas DataFrame df1:
import pandas as pd import numpy as np df1 = pd.DataFrame({ "Name":["Kevin","Peter","James","Jose","Matthew","Pattrick","Alexander"], "Number":[1,2,3,4,5,6,7], "Total":[495.2,432.5,'-',395.5,485.8,415,418.7], "Average_old":[86.57,83.97,'-',96.59,84.67,83.10,83.84], "Grade_old":['A','A','A','A+','A','A','A'], "Total_old":[432.8,419.8,'-',482.9,423.3,415,418.7] })
已通过以下代码计算Average和Grade字段:
df1["Average"] = df1["Total"].apply(lambda x: x/5 + 0.1 if x != "-" else "-") df1["Grade"] = df1["Average"].apply((lambda x:'A+' if x!='-' and x>90 else 'A'))
需要对比Total与Total_old、Average与Average_old、Grade与Grade_old,生成仅包含修改项的dfmod,但遇到两个问题:
- 浮点数精度问题导致Alexander的
Average被误判为修改项(实际计算值与Average_old应为相等) - 使用
np.isclose对比时,因字段中存在'-'字符串触发TypeError
解决方案
步骤1:统一数据类型,替换'-'为NaN
先把所有需要对比的数值型字段中的'-'替换为NaN,方便后续数值处理:
# 定义需要转换的数值字段列表 num_fields = ["Total", "Total_old", "Average", "Average_old"] # 转换为数值类型,无法转换的(即原'-')变为NaN for col in num_fields: df1[col] = pd.to_numeric(df1[col], errors="coerce")
步骤2:编写自定义对比函数
针对不同字段类型(数值/字符串)编写对比逻辑,处理浮点数精度和NaN的情况:
def has_modification(row): # 对比Total和Total_old:数值用isclose,NaN视为相等(原都是'-') total_equal = np.isclose(row["Total"], row["Total_old"], equal_nan=True) if pd.notna(row["Total"]) else True # 对比Average和Average_old:同理处理 avg_equal = np.isclose(row["Average"], row["Average_old"], equal_nan=True) if pd.notna(row["Average"]) else True # 对比Grade和Grade_old:字符串直接相等判断,NaN(原'-')视为相等 grade_equal = (row["Grade"] == row["Grade_old"]) if pd.notna(row["Grade"]) else True # 只要有一个字段不相等,就标记为有修改 return not (total_equal and avg_equal and grade_equal)
步骤3:筛选修改项生成dfmod
用自定义函数标记有修改的行,然后筛选出这些行:
# 生成修改标记列 df1["has_mod"] = df1.apply(has_modification, axis=1) # 筛选出有修改的行,去掉标记列得到dfmod dfmod = df1[df1["has_mod"]].drop(columns=["has_mod"])
验证结果
运行后dfmod会包含以下行:
- Kevin:Total、Average、Grade均有修改
- Peter:Total、Average均有修改
- Jose:Total、Average、Grade均有修改
- Matthew:Total、Average均有修改
而James(全为'-'无修改)、Pattrick(所有字段无修改)、Alexander(Average精度问题已修正,无修改)会被排除,符合预期。
内容的提问来源于stack exchange,提问作者George Sudeep
相关产品推荐
相关产品推荐

