python numpy arange意外的结果
我正在使用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
也许这与浮点数的限制有关。 由于机器的精确性,不可能将所有可能的值作为浮点完美地存储起来。 例如:
>>> 8.4 8.4000000000000004 >>> 8.35 8.3499999999999996
所以,8.4作为浮点比8.4的实际值略大,而8.35作为浮点稍微less一点。
我猜你正在看浮点四舍五入的效果。
numpy.arange
与Python的range
做同样的事情:它不包括“端点”。 (例如range(0, 4, 2)
[0,2,4]
range(0, 4, 2)
将产生[0,2]
而不是[0,2,4]
)
但是,对于浮点步骤来说,舍入误差会累加,偶尔最后一个值实际上会包含端点。
正如在arange
的文档中指出的那样:
当使用非整数步长(如0.1)时,结果往往不一致。 这些情况下最好使用
linspace
。
numpy.linspace
在开始点和结束点之间生成指定数量的点。 顺便说一句,它默认包含端点。
一个函数的帮助说
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,浮点数和string之间的转换现在可以在大多数平台上正确舍入了。
在2.7
>>> float(repr(2.3)) 2.3
在2.6
>>> float(repr(2.3)) 2.2999999999999998
我有同样的问题,我实现了我自己的函数来纠正这个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)