使用Pandas .loc查询chainage(km)部分值返回空DataFrame求助
解决Pandas中浮点数相等查询返回空DataFrame的问题
嘿,这个问题我太熟了——这是典型的浮点数精度坑导致的,我来帮你理清楚原因和解决办法:
为什么会出现这种情况?
咱们平时用的十进制小数(比如0.004),转换成计算机底层的二进制浮点数时,很多时候没法被精确表示,会变成一个无限循环的近似值。当你直接用==去比较DataFrame里存的0.004和你手动写的float(0.004)时,两者的二进制存储其实有细微的差异,这就导致比较结果是False,自然返回空的DataFrame。至于0.001能匹配上,其实是个巧合——刚好它在DataFrame里的存储值和你手动构造的近似值撞在一起了,换个环境说不定也会出问题。
你可以自己验证下这个差异:
print(data['chainage(km)'].iloc[-1]) # 打印DataFrame里的0.004 print(float(0.004)) # 打印手动构造的0.004 print(data['chainage(km)'].iloc[-1] == float(0.004)) # 大概率会输出False
靠谱的解决方案
这里给你几个实用的处理方式,按需选就行:
1. 用numpy的isclose函数(首推)
这个函数会在一个合理的精度范围内判断两个浮点数是否“近似相等”,完美避开精度误差的坑:
import numpy as np result = data.loc[np.isclose(data['chainage(km)'], 0.004)] print(result)
要是你需要更严格的精度控制,还可以通过rtol(相对误差)和atol(绝对误差)参数自定义阈值,比如:
result = data.loc[np.isclose(data['chainage(km)'], 0.004, rtol=1e-09, atol=1e-09)]
2. 四舍五入后再比较
如果你的数据对精度要求没那么高,可以把列值和目标值都四舍五入到指定的小数位,再做比较:
result = data.loc[round(data['chainage(km)'], 3) == round(0.004, 3)] print(result)
3. 转成Decimal类型实现精确比较
要是你需要完全精确的十进制运算,那就把列转换成decimal.Decimal类型,彻底摆脱二进制浮点数的精度问题:
from decimal import Decimal data['chainage(km)'] = data['chainage(km)'].apply(Decimal) result = data.loc[data['chainage(km)'] == Decimal('0.004')] print(result)
4. 读取数据时就控制精度
如果你的数据是从CSV这类文件读进来的,可以在读取时就指定精度,比如用pd.read_csv的float_precision参数:
data = pd.read_csv('your_file.csv', float_precision='round_trip')
内容的提问来源于stack exchange,提问作者user55641
相关产品推荐
相关产品推荐

