df['col'] == 0.1 总是返回全 False 是因浮点数无法精确表示十进制小数,IEEE 754 存储的是近似值 0.10000000000000000555...,直接等于比较必然失败。

为什么 df['col'] == 0.1 总是返回全 False?
这不是 Pandas 的 bug,而是浮点数在二进制中无法精确表示十进制小数(如 0.1)导致的。IEEE 754 双精度实际存储的是近似值 0.10000000000000000555...,所以用 == 直接比较几乎必然失败。
- 所有基于
float64的列都受此影响,包括从 CSV/Excel 读入后未指定类型的数据 -
round()、astype(int)等操作不解决根本问题,中间仍走浮点路径,误差可能放大 -
pd.options.display.float_format只控制显示,不影响底层值,不能用于逻辑判断
读取阶段就避免精度污染:用 dtype='string' + Decimal
对金额、坐标等关键字段,读取时就不该让 Pandas 自动转成 float。直接按字符串读入,后续按需转 Decimal。
- 使用
pd.read_csv(..., dtype={'amount': 'string', 'lat': 'string'}) - 之后用
df['amount'].apply(lambda x: Decimal(x) if pd.notna(x) else None)转高精度数值 - 注意:绝不能用
float(x)中转,那会立刻丢失精度 - 该方法性能较差,只适用于金融字段或中小数据集
计算和比较时别用 ==,改用 np.isclose() 或区间判断
当你必须用浮点列做筛选或断言时,绕过逐位相等比较,改用容差逻辑。
- 筛选:用
np.isclose(df['col'], 0.1)或df['col'].between(0.0999999999, 0.1000000001) - 单元测试断言:用
pandas.testing.assert_series_equal(..., check_exact=False, atol=1e-10) - 归类需求(如把
0.123映射为 “0.1”):优先用np.round(df['col'], decimals=1),它比 Pandas 的round()更稳定 - 转整数倍(如元→分):写成
(df['price'] * 100).round().astype(np.int64),避免链式 float 操作
导出 CSV 时数值变样?关键是 float_format 不等于精度修复
导出后看到 “123.456 变成 123.45600000000001”,说明底层仍是 float,只是输出没截断。
立即学习“Python免费学习笔记(深入)”;
-
to_csv(..., float_format='%.2f')只控制字符串格式,不改变数值本身 - 若需真正保留精度导出,先转
Decimal列,再用astype(str)转字符串导出 - 或者导出前统一乘倍数转整型(如 cents),用
astype(int)后导出,彻底避开浮点
真实精度问题从来不在“怎么显示”,而在于“怎么存”和“怎么算”。字符串读入 + Decimal 计算是最稳妥的金融路径;而大多数分析场景,接受合理容差并用 np.isclose 替代 ==,才是兼顾性能与正确的日常解法。


















