为什么 np.arange(0.6, 0.68, 0.01) 包含 0.68?

问题描述 投票:0回答:2

我在控制台中测试代码并得到了这个:

>>> 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?

我想这可能是数值精度的问题,但我不知道为什么。

python numpy numpy-ndarray
2个回答
1
投票

这确实是一个浮点问题。

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
文档中实际上有关于它的警告:

The length of the output might not be numerically stable.

Another stability issue is due to the internal implementation of numpy.arange. The actual step value used to populate the array is dtype(start + step) - dtype(start) and not step. Precision loss can occur here, due to casting or due to using floating points when start is much larger than step. This can lead to unexpected behaviour. For example:

0
投票

来自官方文档

对于浮点参数,结果的长度为 ceil((stop - 开始)/步骤)。由于浮点溢出,该规则可能会导致 out 的最后一个元素大于 stop。

在这种情况下:

>>> (0.68 - 0.6)/0.01
8.000000000000007

取上限给你

9
,这意味着数值准确性确实是罪魁祸首。 官方文档建议使用
np.linspace
代替浮点范围。

© www.soinside.com 2019 - 2024. All rights reserved.