python 为什么np.arange(0.6,0.68,0.01)包含0.68?[副本]

2hh7jdfx  于 2023-10-14  发布在  Python
关注(0)|答案(3)|浏览(114)

这个问题已经有答案了

numpy arange function returns inconsistent array(1个答案)
昨天关门了。
我在控制台中测试了一段代码,得到了这个:

>>> import numpy as np
>>> np.arange(0.6, 0.68, 0.01)
array([0.6 , 0.61, 0.62, 0.63, 0.64, 0.65, 0.66, 0.67, 0.68])
>>> np.arange(0.6, 0.69, 0.01)
array([0.6 , 0.61, 0.62, 0.63, 0.64, 0.65, 0.66, 0.67, 0.68])
>>> np.arange(0.6, 0.70, 0.01)
array([0.6 , 0.61, 0.62, 0.63, 0.64, 0.65, 0.66, 0.67, 0.68, 0.69])

为什么np.arange(0.6, 0.68, 0.01)包含数字0.68?
我想这可能是数字准确性的问题,但我不知道为什么。

eit6fx6z

eit6fx6z1#

关于official documentation
对于浮点参数,结果的长度是ceil((stop - start)/step)。由于浮点溢出,此规则可能导致out的最后一个元素大于stop。
在这种情况下:

>>> (0.68 - 0.6)/0.01
8.000000000000007

取其上限为9,这意味着数值准确性确实是这里的罪魁祸首。文档建议在指定非整数步长时使用np.linspace

91zkwejq

91zkwejq2#

除了浮点表示是这里的罪魁祸首这一事实之外,其他人已经解释得很好,解决这个问题的方法可以是使用整数(没有这样的表示问题)构建范围并除以精度范围:

np.arange(60,68,1)/100

array([0.6 , 0.61, 0.62, 0.63, 0.64, 0.65, 0.66, 0.67])
n1bvdmb6

n1bvdmb63#

这确实是一个浮点问题。
0.68实际上是0.68000000000000004884981308350688777863979339599609375,因此高于0.68,并将0.68包含在arange中。
如果你取0.69,实际上是0.689999999999999946709294817992486059665679931640625下面0.69),那么你确实有:

np.arange(0.6, 0.69, 0.01)
# array([0.6 , 0.61, 0.62, 0.63, 0.64, 0.65, 0.66, 0.67, 0.68])

实际上在arange文档中有关于它的警告:
输出的长度在数值上可能不稳定。
另一个稳定性问题是由于numpy. arange的内部实现。用于填充数组的实际步长值是dtype(start + step)- dtype(start),而不是step。精度损失可能发生在这里,由于铸造或由于使用浮点时,开始比步大得多。这可能导致意外行为。

相关问题