为什么熊猫数据帧(和Python)有一个奇怪的浮点精度十进制值赋值会影响舍入?

为什么熊猫数据帧(和Python)有一个奇怪的浮点精度十进制值赋值会影响舍入?,python,pandas,dataframe,floating-point,rounding,Python,Pandas,Dataframe,Floating Point,Rounding,希望任何人都能帮助解释以下行为以及如何修复它 我有这样一个数据帧: l = [[1, 50, 3, 4.003], [1, 50, 4, 5.002], [2, 10, 3, 5.003], [2, 50, 2, 5.004]] df = pd.DataFrame(l, columns=["a", "b", "c","d"]) df # Output: a b c d 0 1 50 3

希望任何人都能帮助解释以下行为以及如何修复它

我有这样一个数据帧:

l = [[1, 50, 3, 4.003], [1, 50, 4, 5.002], [2, 10, 3, 5.003], [2, 50, 2, 5.004]]
df = pd.DataFrame(l, columns=["a", "b", "c","d"])

df # Output:
    a   b   c   d
0   1   50  3   4.003
1   1   50  4   5.002
2   2   10  3   5.003
3   2   50  2   5.004
现在,如果我对“d”列第1行和第2行进行简单求和,我应该期望得到
9.005
,对吗? 错了,我得到的是
9.0049999999999
,我就是这样做的:

sum = df.loc[0]["d"] + df.loc[1]["d"]
sum # Output:
9.004999999999999
这会影响总和后四舍五入到小数点后2位的结果

我在互联网上做了一些研究,它可能与float64数据类型上使用的字节数有关,但有没有办法克服这个问题

顺便说一句,当我尝试使用常规python变量时,它会做同样的事情:

d0 = 4.003
d1 = 5.002

d0 + d1 # Output:
9.004999999999999
挑战在于,如果我需要将结果四舍五入到两位小数,我希望得到
9.01
而不是
9.0

round((d0 + d1), 2) # Output:
9.0  # It should have been 9.01

因此,当我们有数千条甚至数百万条记录时,我们必须在求和和和舍入之前确定哪些值存在点精度误差,以避免这个问题,这将是非常不切实际的,还有其他建议吗?

关于第二个示例:您需要使用
十进制
包来避免舍入错误并获得预期结果

from decimal import Decimal

d0 = Decimal('4.003')
d1 = Decimal('5.002')
print(d0 + d1)
print(round(d0 + d1, 2))

9.005
9.00
这篇论文可能会有帮助:

Kahan求和算法(以最小化舍入误差)也可能与此相关:

这是浮点精度错误。您可以添加一个小噪声以获得所需的输出:
round(d0+d1+1e-9,2)
。此外,可能与相关。谢谢@QuangHoang,我如何将其转换为数据帧和?
df['d'].rolling(2).sum()
df['d']+df['d'].shift()。感谢您的帮助,但我不确定这是否是使用
滚动
功能时的预期输出,我的真实数据帧在“d”列中有数千条记录需要求和(按分组),我确实不时注意到,完全相同的输入在舍入后会抛出一个.01甚至.02,原因是这个浮点精度错误,我想我必须先确定哪些值有错误,然后求和。