Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/283.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 为什么x<;=x错误?_Python_Numpy_Precision - Fatal编程技术网

Python 为什么x<;=x错误?

Python 为什么x<;=x错误?,python,numpy,precision,Python,Numpy,Precision,这个标题有点误导,因为它不完全是x和x,而是x和0.3;但是,这些值应该相同 我有: arr = np.arange(0, 1.1, 0.1) 我收到: arr[arr <= 0.3] > array([0., 0.1, 0.2]) arr[arr数组([0,0.1,0.2]) 正确的结果应该是: arr[arr <= 0.3] > array([0., 0.1, 0.2, 0.3]) arr[arr数组([0,0.1,0.2,0.3]) 我还没有偶然发现这个问

这个标题有点误导,因为它不完全是x和x,而是x和0.3;但是,这些值应该相同

我有:

arr = np.arange(0, 1.1, 0.1)
我收到:

arr[arr <= 0.3]
> array([0., 0.1, 0.2])
arr[arr数组([0,0.1,0.2])
正确的结果应该是:

arr[arr <= 0.3]
> array([0., 0.1, 0.2, 0.3])
arr[arr数组([0,0.1,0.2,0.3])

我还没有偶然发现这个问题。我知道它与浮点精度有关……但我在这里能做些什么?

不要依赖于比较浮点数是否相等(除非你确切知道你在处理什么浮点数)。 因为您知道用于生成数组的步长是0.1

arr = np.arange(0, 1.1, 0.1)
您可以将阈值0.3增加步长的一半,以找到一个安全介于
arr
中的值之间的新阈值:

In [48]: stepsize = 0.1; arr[arr < 0.3+(stepsize/2)]
Out[48]: array([ 0. ,  0.1,  0.2,  0.3])
所以数组中的第四个值略大于0.3

In [40]: arr = np.arange(0,1.1, 0.1)
In [41]: arr[3]
Out[41]: 0.30000000000000004

请注意,舍入可能不是可行的解决方案。例如, 如果
arr
具有数据类型
float128

In [53]: arr = np.arange(0, 1.1, 0.1, dtype='float128')

In [56]: arr[arr.round(1) <= 0.3]
Out[56]: array([ 0.0,  0.1,  0.2], dtype=float128)
现在四舍五入不会产生小于0.3的数字:

In [55]: arr.round(1)[3]
Out[55]: 0.30000000000000000001

Unutbu指出了主要问题。你应该避免比较浮点数,因为它们有舍入误差

然而,这是许多人遇到的一个问题,因此有一个函数可以帮助您解决这个问题;
np.isclose
在您的情况下,这将导致:

arr[np.logical_or(arr <= 0.3, np.isclose(0.3, arr))]
>>> array([0., 0.1, 0.2, 0.3])
arr[np.logical\u或(arr>>数组([0,0.1,0.2,0.3])
在这种情况下,这可能不是最好的选择,但了解此函数可能会有所帮助

旁注: 如果没有人向您解释过,为什么会发生这种情况。基本上,计算机以二进制形式保存所有内容,但0.1是二进制形式的周期数,这意味着计算机无法保存所有数字(因为有无限多个)。十进制形式的等价物为:

1/3+1/3+1/3=0.33333+0.33333+0.33333=0.99999


哪一个不是1呢…
arr[arr.round(1)所以,在进行任何比较之前,我是否应该总是对数字进行四舍五入?浮点数之间的等价性总是一件冒险的事情。@Xiphias取决于您的用例-一种方法是将上面的值存储为0-10…并使用普通整数,因为您知道精度,而整数没有浮点数shennigans-但这可能不实用
np.lin对于浮点范围,空格
通常比
np.arange
好得多,特别是它可以更好地控制端点,但它不会使您避免所有舍入错误。即使您不知道步长,也可以执行类似
arr的操作[arr我不知道如何量化
np.arange(…)
中的值与理想的十进制值之间的距离。根据浮点数的不同,连续浮点数之间的差距会发生变化,可能会大于
sys.float\u info.epsilon
。例如,
x=10.3;(np.nextafter(x,np.inf)-x)>sys.float\u info.epsilon
。是的……我会帮我可怜的大脑一个忙,不要去想:)这里有一个例子,add
sys.float\u info.epsilon
是不够的:
x=1.83;arr=np.arange(x,x+1.1,0.1);arr[arr]
In [55]: arr.round(1)[3]
Out[55]: 0.30000000000000000001
arr[np.logical_or(arr <= 0.3, np.isclose(0.3, arr))]
>>> array([0., 0.1, 0.2, 0.3])