20

我正在使用 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 和 < 8.4 的停止值来实现我的结果,但是为什么它不同并且在我看来不一致?

编辑:我使用的是 2.7 版

4

5 回答 5

25

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

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

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

如文档中所述arange

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

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

于 2012-04-04T12:52:47.120 回答
13

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

>>> 8.4
8.4000000000000004
>>> 8.35
8.3499999999999996

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

于 2012-04-04T12:57:30.153 回答
4

范围功能的帮助说

    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
于 2012-04-04T12:54:08.380 回答
2

我遇到了同样的问题,我实现了自己的函数来纠正这个与 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)
于 2017-05-31T13:31:23.030 回答
1

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

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]

于 2021-03-15T15:44:36.417 回答