Python中decimal.Decimal与float比较导致条件判断异常如何解决?
问题原因
核心问题是Decimal类型与float类型的精度不匹配,由两个错误共同导致:
- 初始化DataFrame时先使用了float类型的数值,再调用
apply(Decimal)做转换:float类型的0.0001本身无法被二进制精确存储,实际保存的是一个略小于精确值0.0001的近似值,转成Decimal后这个精度误差也被保留,导致abs(delta) < 0.0001的判断意外成立。 - 条件判断中的阈值全部是float类型,Decimal和float做比较时会触发隐式类型转换,进一步放大精度误差,导致判断逻辑不符合预期。
修复方案
分两步调整代码:
- 初始化OPEN列时直接传入字符串形式的数值转Decimal,避免float的精度损失
- 条件判断中的所有阈值统一改为Decimal类型,保证比较逻辑的精度一致
修正后的完整代码如下:
import pandas as pd import numpy as np from decimal import Decimal # 初始化时直接用字符串转Decimal,避免float精度损失 dt = pd.DataFrame({"OPEN": ["-0.00010","-0.0114", "0.0066","-0.0044","-0.0012","-0.0005", "0.0005","-0.0037", "-0.0029", "0.0034", "0.0003", "0.0001" ]}) dt["OPEN"] = dt["OPEN"].apply(Decimal) def label_change_price(delta): abs_delta = abs(delta) # 所有阈值统一用字符串参数生成精确Decimal if Decimal(0) < abs_delta < Decimal("0.0001"): print(" Return value: ",0, "Delta: ",delta) return 0 elif Decimal("0.0001") <= abs_delta < Decimal("0.0002"): print(" Return value: ",1, "Delta: ",delta) return int(np.sign(delta)) * 1 elif Decimal("0.0002") <= abs_delta < Decimal("0.0003"): print(" Return value: ",2, "Delta: ",delta) return int(np.sign(delta)) * 2 elif abs_delta >= Decimal("0.0003"): print(" Return value: ",3, "Delta: ",delta) return int(np.sign(delta)) * 3 # 应用分类逻辑 dt["label"] = dt["OPEN"].apply(label_change_price)
内容的提问来源于stack exchange,提问作者Jeff
相关产品推荐
相关产品推荐

