Pandas to_numeric数值精度

时间:2018-01-31 16:33:13

标签: python r pandas numpy floating-point

前言

我先说两件事:

背景

我正在努力将项目从R移植到python,并且正在努力寻找一种转换文本到浮动转换过程的好方法。具体来说,我是:

  • 从SQL数据库(pandas.read_sql)中读取pandas数据帧
  • 使用pd_to_numeric将以文本形式存储的列强制转换为数字
    • 使用error='coerce'选项强制从文本强制转换为浮动
    • 检查之前/之后查看输入是否被强制转换为NaN

问题

如何让pandas整齐地将浮动值的文本表示强制转换为相应的float?

我遇到的问题是数值精度。例如:

In[1]: pd.to_numeric('3.785', errors='coerce')
Out[2]: 3.7850000000000001

我理解为什么会发生这种情况(即3.785以在底层二进制表示中不易表现的方式表示)。我想弄清楚的是,是否有办法解决为什么它会有效地发生。

例如,在R中,有很多内容在幕后引发,但在as.numeric API中,您得到表面上由文本值表示的数字:

> as.numeric('3.785')
[1] 3.785

这是我想要的行为。这可能使用pandas / python吗?我打算收纳其他套餐,或被告知“这是不可能的。”#34;

1 个答案:

答案 0 :(得分:1)

我不确定您是否要询问更多有关精度或精度显示(格式化)的信息,但希望这个答案能解决两个问题。

在幕后,r和pandas可能做的完全一样,但是默认显示使它看起来不一样。例如,如果您想更好地了解r如何存储数字,可以执行以下操作:

> sprintf( "%.20f", as.numeric('3.785') )
[1] "3.78500000000000014211"

当然,一旦超过小数点第14位,就超出了可以存储在双精度浮点数中的位数,并且数字并没有真正意义。尽管如此,这至少应该足以表明r并没有真正将其存储为完全 3.785

诚然,要比在某个地方提供更严格的答案,但是实际上,“只要忽略小数点后13位或14位的任何内容”对于标准数据工作来说几乎总是足够的(而且您肯定可以节省开支)不用担心小数点后14位。

我无法确切地说出您使用的熊猫函数为何显示3.7850000000000001而不是3.785的原因,但总的来说,您可以在numpy和pandas的不同部分获得不同级别的默认显示精度。例如,如果仅将[]放在数字周围(以传递列表而不是标量),则pd.to_numeric将输出一个numpy数组,并向您显示更少的小数位:

In [61]: pd.to_numeric(['3.785'], errors='coerce')
Out[61]: array([ 3.785])

如果您通过系列而不是列表,您还将获得类似的显示输出。如果需要特定级别的显示精度,只需明确指定它即可:

In [62]: pd.to_numeric(pd.Series(['3.785']), errors='coerce').map('{:,.20f}'.format)
Out[62]: 
0    3.78500000000000014211

因此,当您明确显示小数点后20位时,在r和pandas / numpy中都会看到相同的数字表示形式。

也许值得一提的是python确实提供了Decimal type并具有精确的小数位数(不同于单精度或双精度浮点数),但是很少将其用于数据科学或数字应用程序不是本地熊猫类型,性能通常会很差。我相信它主要用于会计应用程序。