【问题标题】:python numpy arange unexpected resultspython numpy arange 意外结果
【发布时间】:2012-04-04 12:40:59
【问题描述】:

我正在使用 arange 函数来定义我的 for 循环迭代并得到意想不到的结果。

i = arange(7.8,8.4,0.05)
print i

产生以下结果:

[ 7.8   7.85  7.9   7.95  8.    8.05  8.1   8.15  8.2   8.25  8.3   8.35 8.4 ]

但使用 8.35 的停止值如下

i = arange(7.8,8.35,0.05)

产生以下结果

[ 7.8   7.85  7.9   7.95  8.    8.05  8.1   8.15  8.2   8.25  8.3 ]

但我希望我的范围以 8.35 结束!我知道我可以使用 > 8.35 和

编辑:我使用的是 2.7 版

【问题讨论】:

  • 您使用的是哪个版本的 Python?
  • 避免这些问题的简单方法是使用arrange=(7.8,8.351,0.05)

标签: python numpy


【解决方案1】:

也许它与浮点数的限制有关。由于机器精度,不可能将每个可能的值完美地存储为浮点数。例如:

>>> 8.4
8.4000000000000004
>>> 8.35
8.3499999999999996

因此,作为浮点数的 8.4 略大于 8.4 的实际值,而作为浮点数的 8.35 则略小一些。

【讨论】:

  • 这似乎使用 python 2.6 输出,但使用 2.7,>>>8.4 输出为 8.4
  • 确实如此,这很有趣。看起来他们已经改变了浮点数的打印方式,尽管底层数字仍然相同(稍微不正确),您可以通过比较 Python 2.6 和 2.7 中浮点数的十六进制值来看到。
  • numpy.arange 在 Python 2.7 中也无法正确处理。
  • Python 3.7.3 中的同样问题很高兴知道我不是唯一一个。
【解决方案2】:

向端点添加一点校正器浮点数:

import numpy as np

step = 0.05
corr = 0.01 if step == 0.05 else 0.0

i = np.arange(7.8,8.35+corr,step)
print(i)

输出:

$ python a.py [7.8 7.85 7.9 7.95 8. 8.05 8.1 8.15 8.2 8.25 8.3 8.35]

【讨论】:

    【解决方案3】:

    我猜您看到了浮点舍入的效果。

    numpy.arange 与 python 的range 做同样的事情:它不包括“端点”。 (例如range(0, 4, 2) 将产生[0,2] 而不是[0,2,4]

    但是,对于浮点步骤,舍入误差会累积,有时最后一个值实际上会包含端点。

    arange 的文档中所述:

    当使用非整数步长时,例如 0.1,结果通常不会 始终如一。对于这些情况,最好使用linspace

    numpy.linspace 在起点和终点之间生成指定数量的点。顺便说一句,默认情况下它确实包含端点。

    【讨论】:

    • 嗨 - 我试图在网上找到 linspace 的帮助文档,但奇怪的是空白......你有合适的链接吗?
    • docs.scipy.org/doc/numpy-1.6.0/reference/generated/… 或者,你可以只使用pydoc numpy.linspace,或者如果你在python解释器help(numpy.linspace),或者ipython,它只是numpy.linspace?
    • 这在文档中很清楚,但它不会使 numpy.arange 有用吗?
    【解决方案4】:

    arange 函数的帮助说

        For floating point arguments, the length of the result is
        ``ceil((stop - start)/step)``.  Because of floating point overflow,
        this rule may result in the last element of `out` being greater
        than `stop`.
    

    对于 python 2.7,浮点数和字符串之间的转换现在在大多数平台上都可以正确舍入。

    在 2.7 中

    >>> float(repr(2.3))
    2.3
    

    在 2.6 中

    >>> float(repr(2.3))
    2.2999999999999998
    

    【讨论】:

      【解决方案5】:

      我遇到了同样的问题,我用 numpy.arange 实现了自己的函数来纠正这个舍入问题:

      import numpy as np
      def my_arange(a, b, dr, decimals=6):
          res = [a]
          k = 1
          while res[-1] < b:
              tmp = round(a + k*dr,decimals)
              if tmp > b:
                  break   
              res.append(tmp)
              k+=1
      
          return np.asarray(res)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-03-15
        • 1970-01-01
        • 1970-01-01
        • 2018-12-28
        相关资源
        最近更新 更多