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

如何在Python中正确对DataFrame的close列进行四舍五入?

问题描述

我的DataFrame数据如下:

date        ticker  open    high    low     close   adjClose
2019-07-08  AAPL    50.2025 50.35   49.6025 50.005  48.516
2019-07-09  AAPL    49.8    50.3775 49.7025 50.31   48.8119
2019-07-10  AAPL    50.4625 50.9325 50.39   50.8075 49.2946
2019-07-11  AAPL    50.8275 51.0975 50.4275 50.4375 48.9356
2019-07-12  AAPL    50.6125 51.0    50.55   50.825  49.3116
2019-07-15  AAPL    51.0225 51.4675 51.0    51.3025 49.7748
2019-07-16  AAPL    51.1475 51.5275 50.875  51.125  49.6026
2019-07-17  AAPL    51.0125 51.2725 50.8175 50.8375 49.3237
2019-07-18  AAPL    51.0    51.47   50.925  51.415  49.884

我需要将close列四舍五入到两位小数,尝试过以下方法:

df['close'] = round(df['close'], 2)
df.loc[:, 'close'] = df.loc[:, 'close'].round(2)
df.loc[:, 'close'] = df.loc[:, 'close'].apply(lambda x: Decimal(x).quantize(Decimal('0.01'), rounding=ROUND_HALF_UP))
df.loc[:, 'close'] = df.loc[:, 'close'].apply(lambda x: Decimal(x).quantize(Decimal('0.01')))
df.loc[:, 'close'] = np.round(df.loc[:, 'close'], 2)

但结果不符合预期:

  • 2019-07-18行的close值应为51.42,实际得到51.41
  • 部分方法无法正确处理50.005(应得50.01)和50.825(应得50.83)
解决方案

问题根源是浮点数精度误差:像51.415这样的十进制数无法被二进制浮点数精确表示,实际存储的是接近但略小于51.415的数值(比如51.41499999999999...),导致舍入时被截断为51.41。

要解决这个问题,需要避免直接对二进制浮点数进行舍入操作,而是基于精确的十进制数值处理:

方法1:读取数据时直接使用Decimal类型

在读取CSV时指定dtype保留字符串格式,再转换为Decimal类型进行舍入:

from decimal import Decimal, ROUND_HALF_UP
import pandas as pd

# 读取数据时保留close列的字符串格式
df = pd.read_csv('aapl.csv', dtype={'close': str})
# 转换为Decimal并按要求舍入到两位小数
df['close'] = df['close'].apply(lambda x: Decimal(x).quantize(Decimal('0.01'), rounding=ROUND_HALF_UP))
# 可选:转换回float类型(如果后续需要数值计算)
df['close'] = df['close'].astype(float)

方法2:放大数值规避浮点数精度问题

将数值乘以100转换为整数,避免精度误差后再舍入,最后缩小回原尺度:

import pandas as pd

df['close'] = (df['close'] * 100 + 0.5).astype(int) / 100

注意:该方法仅适用于常规数值场景,极端数值可能仍存在精度问题,优先推荐方法1。

方法3:基于现有浮点数列转字符串后处理

如果已加载浮点数列,可先将数值转为字符串再用Decimal处理:

from decimal import Decimal, ROUND_HALF_UP
import pandas as pd

df['close'] = df['close'].apply(lambda x: Decimal(str(x)).quantize(Decimal('0.01'), rounding=ROUND_HALF_UP))
验证结果

处理后的close列应为:

50.01
50.31
50.81
50.44
50.83
51.30
51.13
50.84
51.42

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 22:21:57