Pandas .loc判断浮点数相等时无法返回预期非空DataFrame
浮点精度问题排查与解决
问题背景
我创建了一个float64类型的计算列,预设保留两位小数,计算公式为:
data['Engine Efficiency'] = 4.0 * data['Engine Displacement'] / (data['# Cylinders'].astype('float64') * 3.24)
尝试通过以下方式筛选值为0.62的行:
- 直接等值匹配:
data.loc[data['Engine Efficiency'] == 0.62] - 浮点精度匹配:
data[np.isclose(data['Engine Efficiency'], 0.62)] - 自定义容差匹配:
data[np.abs(data['Engine Efficiency'] - float(0.62)) < 0.0001*float(0.62)]
所有方法均返回空DataFrame,但判断!=0.62时返回全量数据,推测是计算过程中的数值精度问题。已尝试修改计算公式、替换math.pi/np.pi、设置精度、统一转换浮点类型等方法,均未解决。
排查与解决步骤
1. 查看数值真实精度
先提取疑似等于0.62的行,打印其精确值,确认误差范围:
# 打印前10行的高精度数值 print(data['Engine Efficiency'].head(10).apply(lambda x: format(x, '.20f')))
这能直观看到数值是否是0.6199999999999999或0.6200000000000001这类接近0.62但存在微小误差的情况。
2. 调整容差参数
如果是np.isclose的默认容差不够,放宽相对/绝对容差:
# 增大容差范围,适配两位小数的误差 data[np.isclose(data['Engine Efficiency'], 0.62, rtol=1e-4, atol=1e-6)] # 或者直接用两位小数的绝对误差范围 data[np.abs(data['Engine Efficiency'] - 0.62) < 0.005]
3. 计算后强制四舍五入
既然预设保留两位小数,计算后直接对列做四舍五入处理,再进行等值筛选:
# 计算时直接保留两位小数 data['Engine Efficiency'] = round(4.0 * data['Engine Displacement'] / (data['# Cylinders'].astype('float64') * 3.24), 2) # 之后直接等值匹配 data.loc[data['Engine Efficiency'] == 0.62]
4. 升级数据类型
尝试用更高精度的浮点类型(如float128)进行计算,减少精度损失:
data['Engine Displacement'] = data['Engine Displacement'].astype('float128') data['# Cylinders'] = data['# Cylinders'].astype('float128') data['Engine Efficiency'] = 4.0 * data['Engine Displacement'] / (data['# Cylinders'] * 3.24)
内容的提问来源于stack exchange,提问作者Nežumi
相关产品推荐
相关产品推荐

