我正在使用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版
答案 0 :(得分:20)
我猜你正在看到浮点舍入的影响。
numpy.arange
与python的range
做同样的事情:它不包括“端点”。 (例如range(0, 4, 2)
将产生[0,2]
而不是[0,2,4]
)
但是,对于浮点步骤,舍入错误会累积,有时最后一个值实际上会包含端点。
正如arange
的文档中所述:
使用非整数步骤(例如0.1)时,结果通常不会 始终如一。对这些案例最好使用
linspace
。
numpy.linspace
在起点和终点之间生成指定数量的点。顺便提一下,它默认包含端点。
答案 1 :(得分:9)
也许它与浮点数的限制有关。由于机器精度,不可能将每个可想到的值完美地存储为浮点。例如:
>>> 8.4
8.4000000000000004
>>> 8.35
8.3499999999999996
因此,8.4作为浮点略大于实际值8.4,而作为浮点的8.35稍微小一些。
答案 2 :(得分:3)
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
in 2.6
>>> float(repr(2.3))
2.2999999999999998
答案 3 :(得分: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)
答案 4 :(得分:0)
向端点添加一点校正器浮点数:
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]