此方案是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
类型时舍入不能正常工作?
答案 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。