You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何正确对pandas DataFrame的两列float数值做减法避免精度损失

问题原因

  1. 列名拼写错误:你定义的DataFrame列名是全大写的OPEN、CLOSE,但代码里用的是"Close"、"Open",大小写不匹配会读取不到正确值。
  2. 循环边界错误:dt.size返回的是DataFrame总元素个数(你示例的dt是12行2列,size为24),直接循环到dt.size-1会出现行索引越界。
  3. Decimal精度设置不生效的核心原因:getcontext().prec控制的是Decimal运算过程的有效数字位数,不会限制从float转换Decimal时的精度。float本身是二进制存储的,很多十进制小数没法精确表示,你直接把float丢给Decimal构造函数,会把float底层的二进制近似值完整转过来,自然会出现很长的小数位。

解决方案

方案1:保留Decimal方案(适合对精度要求极高的场景)

核心是不要直接从float转Decimal,先把数值格式化为对应精度的字符串再转换,就能避开float的二进制误差:

import pandas as pd
import numpy as np
from decimal import Decimal, getcontext
# 控制运算精度为6位有效数字
getcontext().prec = 6

dt = pd.DataFrame({"OPEN": [-0.00011,-0.0114, 0.0066,-0.0044,-0.0012,-0.0005,
                             0.0005,-0.0037, -0.0029, 0.0034, 0.0003, 0.0001 ],
                   "CLOSE": [-1.20011,-3.0114, 0.4066,-0.0074,-0.0016,-5.0005,
                             0.0225,-0.0027, -0.0026, 0.0064, 0.0043, 4.0001 ],})

delta = []
for i in range(len(dt)):
    # 先转成5位小数的字符串再转Decimal,避开float原生精度误差
    open_val = Decimal(f"{dt.loc[i,'OPEN']:.5f}")
    close_val = Decimal(f"{dt.loc[i,'CLOSE']:.5f}")
    delta_val = open_val - close_val
    delta.append(float(delta_val)) # 也可以根据需求直接存Decimal类型

dt["delta"] = delta

方案2:更简单的pandas原生方案(适合4-5位精度的常规场景)

你需要的精度只有5位,直接做减法后保留5位小数即可,完全能覆盖需求,代码更简洁、性能也更好:

dt["delta"] = (dt["OPEN"] - dt["CLOSE"]).round(5)

该方案完全匹配你提到的0.0003-0.0002得到0.0001的输出要求。

内容的提问来源于stack exchange,提问作者Jeff

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 18:54:03