舍入差异-float64与float32

时间:2020-07-17 19:34:01

标签: python pandas

此方案是ETL方案的简化,其中涉及从MySQL表提取的多组数据。我有一个合并的数据框,其中一个价格列的类型为float64,而另一个价格列的类型为object

import pandas as pd

df = pd.DataFrame({
    'price1': [0.066055],
    'price2': ['0.066055'],
})

>>> df.dtypes
price1    float64
price2     object
dtype: object

将这两列转换为float64时,将price1列舍入到5位数字时舍入不正确。

float64_df = df[price_cols].apply(lambda x: pd.to_numeric(x))

>>> float64_df.dtypes
price1    float64
price2    float64
dtype: object

>>> float64_df[price_cols].apply(lambda x: x.round(5))
    price1   price2
0  0.06606  0.06605

但是,当使用float32将列转换为downcast='float'时,舍入将按预期进行。

float32_df = df[price_cols].apply(lambda x: pd.to_numeric(x, downcast='float'))

>>> float32_df.dtypes
price1    float32
price2    float32
dtype: object

>>> float32_df[price_cols].apply(lambda x: x.round(5))
    price1   price2
0  0.06606  0.06606

有什么想法为什么当两列均为float64类型时舍入不能正常工作?

3 个答案:

答案 0 :(得分:2)

以更高的精度打印浮标表明pd.to_numeric'.066055'转换为0.06605499999999998872

with pd.option_context('display.float_format', '{:0.20f}'.format):
    print(float64_df)

输出:

                  price1                 price2
0 0.06605500000000000260 0.06605499999999998872

答案 1 :(得分:1)

简短的答案是pd.to_numeric为两者输出不同的值:

pd.to_numeric(0.066055)
pd.to_numeric('0.066055')

# 0.066055
# 0.06605499999999999

对于0.066055,它是simply returns the value

对于'0.066055',我相信它使用this function将字符串转换为浮点数。

This answer可能也有帮助。

答案 2 :(得分:0)

用浮点数获取准确的数字在某种程度上是不可能的,并且浮点数总是有些不可预测的。我的猜测是该对象产生的float64比原始数字小一点,例如0.066054999999999999或类似的东西,导致意外的舍入结果。

Python对此有一些documentation