Numpy 的舍入方式与 Python 不同

2024-05-08

The code

import numpy as np
a = 5.92270987499999979065
print(round(a, 8))
print(round(np.float64(a), 8))

gives

5.92270987
5.92270988

知道为什么吗?

在 numpy 来源中找不到任何相关内容。

Update:
我知道处理这个问题的正确方法是以这种差异无关紧要的方式构建程序。我就是这么做的。我在回归测试中偶然发现了它。

Update2:
关于@VikasDamodar 评论。人们不应该相信repr()功能:

>>> np.float64(5.92270987499999979065)
5.922709875
>>> '%.20f' % np.float64(5.92270987499999979065)
'5.92270987499999979065'

Update3:
在 python3.6.0 x32、numpy 1.14.0、win64 上测试。也在 python3.6.4 x64、numpy 1.14.0、debian 上。

Update4:
只是要确定:

import numpy as np
a = 5.92270987499999979065
print('%.20f' % round(a, 8))
print('%.20f' % round(np.float64(a), 8))

5.92270987000000026512
5.92270988000000020435

Update5:
下面的代码演示了差异发生在哪个阶段,而不使用str:

>>> np.float64(a) - 5.922709874
1.000000082740371e-09
>>> a - 5.922709874
1.000000082740371e-09
>>> round(np.float64(a), 8) - 5.922709874
6.000000496442226e-09
>>> round(a, 8) - 5.922709874
-3.999999442783064e-09

显然,在应用“round”之前,它们是相同的数字。

Update6:
与@user2357112的答案相反,np.round大约比圆形慢 4 倍:

%%timeit a = 5.92270987499999979065
round(a, 8)

1.18 µs ± 26.5 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)  

%%timeit a = np.float64(5.92270987499999979065)
round(a, 8)

4.05 µs ± 43.9 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

也在我看来np.round甚至比内置的四舍五入效果更好round:最初我通过将 11.84541975 除以二得到这个 5.92270987499999979065 数字。


float.__round__ https://github.com/python/cpython/blob/v3.6.4/Objects/floatobject.c#L905使用正确舍入的双精度到字符串算法,特别注意生成正确舍入的结果。

NumPy 没有。这NumPy 文档 https://docs.scipy.org/doc/numpy/reference/generated/numpy.around.html#numpy.around提到这一点

由于 IEEE 浮点标准 [R9] 中十进制小数的不精确表示,结果也可能令人惊讶按 10 次方缩放时引入的错误.

这更快,但会产生更多舍入误差。它会导致像您所观察到的错误,以及更明确地低于截止值的数字仍然被四舍五入的错误:

>>> x = 0.33499999999999996
>>> x
0.33499999999999996
>>> x < 0.335
True
>>> x < Decimal('0.335')
True
>>> x < 0.67/2
True
>>> round(x, 2)
0.33
>>> numpy.round(x, 2)
0.34000000000000002

NumPy 的舍入时间变慢,但这与哪种舍入算法较慢没有任何关系。 NumPy 和常规 Python 数学之间的任何时间比较都可以归结为 NumPy 针对整个数组运算进行了优化。对单个 NumPy 标量进行数学运算会产生大量开销,但对整个数组进行舍入numpy.round轻松击败对浮点数列表进行四舍五入round:

In [6]: import numpy

In [7]: l = [i/7 for i in range(100)]

In [8]: a = numpy.array(l)

In [9]: %timeit [round(x, 1) for x in l]
59.6 µs ± 408 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

In [10]: %timeit numpy.round(a, 1)
5.27 µs ± 145 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

至于哪个更准确,那肯定是float.__round__。你的数字更接近 5.92270987,而不是 5.92270988,而且它是圆形的 -ties- 为偶数,而不是所有内容都为偶数。这里没有领带。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Numpy 的舍入方式与 Python 不同 的相关文章

随机推荐

  • 使填充的值成为ggplot2中的实际填充

    有没有办法让填充的值 标签 成为填充本身 例如 在堆积条形图中 我有 require ggplot2 big votes movies movies movies votes gt 100000 p ggplot big votes mov
  • Objective-c:如何创建不同深浅的颜色

    是否有任何算法可以为给定的十六进制或 RGB 值创建不同的阴影 我尝试过增加和减少 alpha 但浅色 例如 白色 看起来不太好 实现此目的的最佳方法是使用 HSB 色彩空间 这就是我在最新的应用程序中完成键盘左手部分的方式 颜色的 阴影
  • 如何在rails中定义自定义路径?

    我有一个用户模型 如果我做 def my action user User new end then I get undefined method users path for
  • 在 Cocoa 中实现源代码语法高亮的最佳方法是什么? [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我正在开发 Cocoa 应用程序 它应该能够分析和突出显示用 Objective C SQL JavaS
  • git am:补丁格式检测失败

    我以前从未在 Git 中使用过补丁 我需要一些帮助 我正在尝试将补丁应用到 Git 存储库来测试 Wine 补丁 特别是这个补丁在这里 https bugs winehq org attachment cgi id 60752 所以我做了以
  • 如何从同一网络中的另一台计算机访问我的 nodejs-express 本地主机服务器?

    我努力了this https stackoverflow com questions 5524116 accessing localhost xampp from another computer over lan network how
  • xpath 的多个 string() 结果?

    string 在我试图从中提取文本的某个网页上效果很好 具有类似的结构 对于 bing 我尝试过的 xpath 是 string h3 a 即使有强标签等 它也能很好地获取搜索结果 但只返回第一个结果 有没有类似 strings 的东西 这
  • 将 for 循环中的值传递给事件侦听器 - Javascript [重复]

    这个问题在这里已经有答案了 可能的重复 使用 Google Maps API v3 循环遍历标记问题 https stackoverflow com questions 2670356 looping through markers wit
  • 闪亮的如何阻止用户访问选项卡?

    我需要阻止用户访问其他选项卡 直到完成某些操作 在这个可重现的示例中 我想阻止用户访问Tab 2直到他按下按钮 该应用程序如下所示 这是该应用程序的代码 library shiny ui lt shinyUI navbarPage tabP
  • 如何真正释放 Linux 中的大页面以供新进程使用?

    真的找不到太多关于此的信息 希望有人可以提供帮助 我正在假脱机使用 100GB java 堆作为大数据缓存 为了避免与文件系统缓存等内容发生冲突 并且因为它通常性能更好 我将其分配在大页面中 我保留了 51 200 x 2MB 大页面 一切
  • 如何在 VS Code 中集成 babun shell

    我尝试过更改设置 terminal integrated shell windows to babun mintty地点 但是 babun shell 窗口单独打开 并且不与 VS code 集成 有人知道如何实现这一目标吗 经过2个小时的
  • 如何强制send_data在浏览器中下载文件?

    好吧 我的问题是我正在使用send data on my Rails 3应用程序向用户发送文件AWS S3类似的服务 Base establish connection access key id gt my key secret acce
  • Python 使用 pandas 和 str.strip 崩溃

    这段最少的代码使我的 Python 崩溃了 设置 pandas 0 13 0 python 2 7 3 AMD64 Win7 import pandas as pd input file r c3 csv input df pd read
  • Google Pub/Sub 是否有队列或主题?

    我熟悉 JMS 对 Google Pub Sub 还很陌生 在 JMS 中有 2 个选项 Queue 只有一个消费者可以接受消息 Topic 每个消费者接受来自主题的每条消息 我相信 Google Pub Sub 应该支持这样的东西 但是快
  • 如何通过值获取 JavaScript“Map”中的键?

    我有一个像这样的 JavaScript 地图 let people new Map people set 1 jhon people set 2 jasmein people set 3 abdo 我想要某种方法按值返回键 let jhon
  • 通过vba在每个空间范围之间添加求和公式

    我试图进行自动化 但我被困在这里 我需要在空间范围之间动态添加总和公式 我完全迷失了使用 VBA 添加公式的能力 任何人都可以帮助我 先感谢您 我假设您想要的是 如果单元格中有空白 您希望将所有其他元素相加并将结果放置在该空白中 可能有很多
  • 没有找到任务运行程序配置?

    我有 新安装的 Visual Studio Professional 2017 V 15 9 4 视觉工作室解决方案 https learn microsoft com en us visualstudio ide solutions an
  • 尝试使用 python 连接 mongodb atlas 时连接超时

    我正在尝试连接到我的 mongodb atlas 集群 但是当我尝试对我的数据库执行某些操作时 我总是超时 我使用的数据库是在 mongoshell 中创建的 也是我在 mongodb compass 中检查它们是否存在的集合 ERROR
  • 工作站和嵌入式程序员之间的心态差异[关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • Numpy 的舍入方式与 Python 不同

    The code import numpy as np a 5 92270987499999979065 print round a 8 print round np float64 a 8 gives 5 92270987 5 92270