如何在Python中消除浮点数不精确性问题

4
我正在编写一个程序,比较和排列日期序列中的值非常重要。但是,由于浮点数的不精确性,我遇到了一些问题。
我从SQL服务器中提取这些数据,它们都应该是1.6。然而,它们的值略有不同(见下文)。因此,当我使用dataframe.rank()时,它并不将这两个日期视为相同的排名,而是将01/02/2004排在02/01/2005之上。
有人有什么想法来解决这个问题,使得这两个日期最终有相同的排名吗?
modelInputData.loc['01/02/2004',('Level','inflationCore','EUR')]
Out[126]: 1.6000000000000003

modelInputData.loc['02/01/2005',('Level','inflationCore','EUR')]
Out[127]: 1.6000000000000001

1
Python浮点数问题和限制的文档:https://docs.python.org/2/tutorial/floatingpoint.html。 - Jason De Arte
1
听起来浮点数在这里不是正确的解决方案。如果需要进行任意精度的计算,请使用十进制而不是浮点数: https://docs.python.org/2/library/decimal.html#module-decimal - Nick Bailey
是的,我可能最终会这样做。谢谢! - jjvandermade
很遗憾,decimal.Decimal不支持转换pandas Dataframe/Series(或任何类似列表的对象)。至少我无法弄清楚。因此,我将整个内容乘以100并转换为整数。 - jjvandermade
2个回答

6

如果数字比您选择的任何精度更小怎么办? - Roland Smith
1
准确性问题实际上仍然存在,但奇怪的是它们现在相同了(1.6000000000000001)。总的来说,四舍五入并不能解决精度问题。 - jjvandermade

2
我建议您像银行家一样使用分和整数,而不是使用 EUR/USD 和浮点/十进制变量。可以在 MySQL 端将其转换为分,或者在 pandas 中进行转换:
df['amount'] = round(df['amount']*100)

您将会遇到更少的问题。

1
请在此处使用 round;直接使用 int 会有意外截断值的风险。例如:int(0.29 * 100) -> 28 - Mark Dickinson
@MarkDickinson,你说得完全正确,感谢你指出来!我已经修改了我的回答。 - MaxU - stand with Ukraine

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接