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

使用np.trunc截断Pandas数据框小数位时出现异常舍入问题求助

解决Pandas浮点数截断三位小数的异常问题

出现这种异常是浮点数精度误差导致的:十进制小数(比如0.87、59.307)无法被二进制浮点数精确存储,实际存储值会有微小偏差——比如0.87可能存成0.8699999999999999,59.307存成59.306999999999996。当你执行np.trunc(df['QuantityReq']*1000)/1000时,这些偏差会被放大:0.8699999999999999×1000=869.9999999999999,np.trunc直接截断小数部分得到869,最终除以1000就是0.869,和预期不符。

解决方案

1. 用decimal模块精确处理(最可靠)

通过decimal模块直接以十进制逻辑运算,从根源避免二进制浮点数的精度损失:

from decimal import Decimal, ROUND_DOWN

def truncate_to_three(x):
    # 先转字符串再初始化Decimal,避免浮点数转Decimal时的精度丢失
    return Decimal(str(x)).quantize(Decimal('0.000'), rounding=ROUND_DOWN)

df['Test'] = df['QuantityReq'].apply(truncate_to_three).astype(float)

2. 加极小偏移量修正(简便快速)

针对浮点数的微小负偏差,给原数值加一个极小的正数(比如1e-10),再执行截断操作:

import numpy as np

df['Test'] = np.trunc((df['QuantityReq'] + 1e-10) * 1000) / 1000

注意:偏移量要足够小(不能超过0.0005),避免影响真正需要截断的小数部分。

3. 字符串格式化截断(适合简单场景)

通过字符串截取实现截断,注意处理整数和科学计数法的情况:

def truncate_str(x):
    # 处理科学计数法
    if 'e' in str(x).lower():
        x = float(f"{x:.10f}")
    parts = str(x).split('.')
    if len(parts) == 1:
        return float(f"{parts[0]}.000")
    else:
        # 截取前3位小数,不足补0
        decimal_part = parts[1][:3].ljust(3, '0')
        return float(f"{parts[0]}.{decimal_part}")

df['Test'] = df['QuantityReq'].apply(truncate_str)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 22:25:41