Pandas/Numpy round函数对DataFrame列四舍五入异常求助
解决numpy.round处理64.545保留两位小数的舍入异常
问题描述
使用np.round()对DataFrame的REVENUE列保留两位小数时,出现异常情况:64.5450未按预期进位为64.5500,反而得到64.5400,其余数值舍入正常。
示例数据与执行结果:
sample['REVENUE'] 12830 0.0000 12831 3.3600 12832 3.1680 12833 13.0061 12834 13.2150 12835 64.5450 12836 113.5350 12837 245.0000 12838 27.7750 Name: REVENUE, dtype: float64 np.round(sample['REVENUE'], decimals = 2) 12830 0.0000 12831 3.3600 12832 3.1700 12833 13.0100 12834 13.2200 12835 64.5400 # 异常:预期64.5500 12836 113.5400 12837 245.0000 12838 27.7800 Name: REVENUE, dtype: float64
原因分析
这是浮点数精度局限性导致的问题:64.545在二进制浮点数体系中无法精确表示,实际存储的数值略小于64.545,因此np.round()进行舍入时会向下取整。
解决方法
方法1:使用pandas内置的round方法
pandas的Series.round()针对这类浮点数精度问题做了优化,能得到符合预期的舍入结果:
sample['REVENUE'].round(2)
执行后64.5450会被正确舍入为64.5500。
方法2:使用decimal模块实现精确十进制舍入
通过decimal模块以十进制精度处理数值,避免二进制浮点数的误差:
from decimal import Decimal, ROUND_HALF_UP def precise_round(x): # 将浮点数转为Decimal对象,按四舍五入保留两位小数 return Decimal(str(x)).quantize(Decimal('0.00'), rounding=ROUND_HALF_UP) # 应用到列上 sample['REVENUE'] = sample['REVENUE'].apply(precise_round)
方法3:添加极小值修正浮点数精度
给目标数值添加一个极小的epsilon(如1e-8),修正存储的微小误差后再进行舍入:
np.round(sample['REVENUE'] + 1e-8, decimals=2)
这个方法能让略小于64.545的存储值被修正为接近真实值,从而触发正确的进位。
内容的提问来源于stack exchange,提问作者Jason Lim
相关产品推荐
相关产品推荐

