它偶然发现 Pandas 和 Python 在舍入时表现不同的情况。
>>> import pandas as pd
>>> numbers = [0.495,1.495,2.495,3.495,4.495,5.495,6.495, 7.495,8.495, 9.495, 10.495]
>>> [round(float(x),2 ) for x in numbers]
[0.49, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, 8.49, 9.49, 10.49]
>>> pd.DataFrame(numbers).astype(float).round(2)
0
0 0.50
1 1.50
2 2.50
3 3.50
4 4.50
5 5.50
6 6.50
7 7.50
8 8.49
9 9.49
10 10.50
为什么 Pandas 的舍入
0.495
和 10.495
与 Python 不同?我想从Python 3开始都实现了银行家四舍五入?一种实现比另一种更正确吗?
答案基本上是来自@ouroboros1的评论给出的。事实证明,Pandas 在幕后使用了 np.round。
np.round()
的文档提到:
“[它]使用快速但有时不精确的算法来舍入浮点数据类型,...[而]Python 的内置舍入函数对 64 位浮点值使用更准确但较慢的算法。”
我只想详细说明“不精确”在我们的示例中的含义。如果我们将示例中的数字相加而不进行四舍五入,我们会得到
>>> sum(numbers)
60.445
如果我们将 Pandas 舍入的数字相加,我们会得到
>>> pd.DataFrame(numbers).round(2).sum()
0 60.48
如果我们将 Python 舍入的数字相加,我们会得到
>>> sum([round(x, 2) for x in numbers])
60.46
因此,在使用多个舍入数字进行计算时,Python 的舍入算法提供的结果比使用 Pandas 舍入函数更接近准确的结果。
但是,为了更接近准确的结果,您应该只在计算结束时进行舍入
>>> pd.DataFrame(numbers).sum().round(2). # better than round(2).sum()
0 60.44
但在这种情况下,最佳/预期结果也是由 Python
round()
函数给出的
>>> round(sum(numbers),2)
60.45
总结一下:在计算中尽可能晚地舍入。如果您追求精度而不是速度,则更喜欢 Python
round()
函数而不是 Pandas 舍入。