有比Numpy arange()更好的选择吗



对于下面的代码,我希望范围停止在值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使用了一个非常相似的公式,但只要你使用有理数,上面的代码在你的用例中可能更容易掌握——你不必自己计算步数。(