对于下面的代码,我希望范围停止在值1.0,但它一直上升到1.099999…,这是有意义的,因为它是一个浮点值。
用0.1的步长创建这个范围的更好方法是什么?
import numpy as np
start = 0.5
stop = 1.0
step = 0.1
for parameter_value in np.arange(start, stop + step, step):
print(parameter_value)
输出
0.5
0.6
0.7
0.7999999999999999
0.8999999999999999
0.9999999999999999
1.0999999999999999
您不能用二进制IEEE 754格式精确地表示0.1,这是大多数现代体系结构内部用来表示浮点数的格式。
最接近0.1的二进制值只是真相之下的一个阴影。当你把这个最接近的近似值加五次时,误差就会增加。
根据np.arange
:的文档
当使用非整数步长(如0.1(时,结果通常不一致。对于这些情况,最好使用
numpy.linspace
。
原因是通过夹紧端部,linapace
可以对累积误差做出一些arange
无法保证的保证。linspace
使用的每个单独步骤可能不是0.1的最接近二进制表示,但每个元素从开始到结束都将尽可能接近n * 0.1
。
np.arange(0.5, 1.1, 0.1)
对应的linapace
调用为
np.linspace(0.5, 1.0, 6)
linspace
的另一个优点是可以固定点数。同样根据arange
文档(返回值(:
对于浮点参数,结果的长度为
ceil((stop - start)/step)
。由于浮点溢出,此规则可能导致out的最后一个元素大于stop。
作为一种替代方案,您可以使用除法不会像迭代加法那样产生那么多错误的事实。这与浮点运算一样精确:
np.arange(5, 11) / 10.0
# => array([0.5, 0.6, 0.7, 0.8, 0.9, 1. ])
(np.linspace
使用了一个非常相似的公式,但只要你使用有理数,上面的代码在你的用例中可能更容易掌握——你不必自己计算步数。(