【问题标题】:Pandas to_numeric numerical precisionPandas to_numeric 数值精度
【发布时间】:2018-07-10 20:23:15
【问题描述】:

前言

我先说两件事:

背景

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

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

问题

如何让 pandas 巧妙地将浮点值的文本表示强制转换为相应的浮点数?

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

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

这是我想要的行为。这可能使用熊猫/python吗?我愿意合并其他软件包,或者被告知“这是不可能的”。

【问题讨论】:

  • 更长的答案:是的。确保您使用的是 NumPy >= 1.14.0。您在此处看到的输出数字是 NumPy float64 实例,并且 NumPy 1.14.0 更改了浮点打印功能,以便您可以更频繁地看到简洁的表示。
  • 谢谢@MarkDickinson!这正是我一直在寻找/希望的。我真的很感激。
  • @cᴏʟᴅsᴘᴇᴇᴅ:我认为副本不太合适
  • @MarkDickinson 重新打开,我的错误。欢迎回答。

标签: python r pandas numpy floating-point


【解决方案1】:

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

在幕后,r 和 pandas 很可能在做完全相同的事情,但默认显示却让它看起来不一样。例如,如果您想更好地了解 r 是如何存储数字的,您可以这样做:

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

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

诚然,在某个地方有比这个更严格的答案,但实际上“忽略小数点后 13 或 14 位的任何内容”对于标准数据工作几乎总是足够的(而且你几乎肯定最好还是花钱不用担心小数点后第 14 位)。

我不能确切地说为什么您使用的 pandas 函数显示 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,它具有精确的小数(与单精度或双精度浮点数不同),但很少将其用于数据科学或数值应用程序,因为它不是原生 pandas 的类型和性能通常会很差。我相信它主要用于会计应用程序。

【讨论】:

    猜你喜欢
    • 2016-08-17
    • 2018-01-23
    • 2018-07-09
    • 2023-02-13
    • 2017-10-03
    • 1970-01-01
    • 2016-10-16
    • 2020-07-29
    • 1970-01-01
    相关资源
    最近更新 更多