标题有点误导,因为它不完全是x和x,它是x和0.3;然而,值应该是相同的。为什么x <= x false?
我:
arr = np.arange(0, 1.1, 0.1)
,我得到:
arr[arr <= 0.3]
> array([0., 0.1, 0.2])
正确的结果应该是:
arr[arr <= 0.3]
> array([0., 0.1, 0.2, 0.3])
我还没有偶然发现了这个问题。我知道它与浮点精度有关......但我能在这里做什么?
标题有点误导,因为它不完全是x和x,它是x和0.3;然而,值应该是相同的。为什么x <= x false?
我:
arr = np.arange(0, 1.1, 0.1)
,我得到:
arr[arr <= 0.3]
> array([0., 0.1, 0.2])
正确的结果应该是:
arr[arr <= 0.3]
> array([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])
顺便说一句,在np.arange(0, 1.1, 0.1)
的1.1
是同样的想法的一个应用 - 定的浮点运算的变幻莫测,我们也不能肯定这1.0
将是如果我们写了np.arange(0, 1.0, 0.1)
,那么这个结果就会增加,所以右边的终点增加了stepize。
从根本上说,这个问题归结为floating-point arithmetic being inaccurate:
In [17]: 0.1+0.2 == 0.3
Out[17]: False
所以在阵列中的第四值大于0.3一点点。
In [40]: arr = np.arange(0,1.1, 0.1)
In [41]: arr[3]
Out[41]: 0.30000000000000004
注意,舍入可能不是一个可行的解决方案。例如, 如果arr
具有D型细胞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)
虽然使float128
制成arr[3]
接近小数0.3 D型,
In [54]: arr[3]
Out[54]: 0.30000000000000001665
现在四舍五入不会产生数小于0.3:
In [55]: arr.round(1)[3]
Out[55]: 0.30000000000000000001
即使你不知道步长,你*仍然可以做类似'arr [arr <= 0.3 + sys.float_info.epsilon] - 但是,我并不完全相信它会*总是*足以保证比较工作...你有什么想法? –
虽然 - 上面似乎也适用于你的'float128'范例... –
我不确定如何量化'np.arange(...)'中的值可能离他们多远理想化的小数对应。根据浮点数,连续浮点数之间的差距会发生变化,并且可能会大于'sys.float_info.epsilon'。例如, 'x = 10.3; (np.nextafter(x,np.inf) - x)> sys.float_info.epsilon'。 – unutbu
Unutbu指出了主要问题。您应该避免比较浮点数,因为它们有四舍五入的错误。
然而,这是一个很多人遇到的问题,因此有一个函数可以帮助你解决这个问题; np.isclose
你的情况,这将导致:
arr[np.logical_or(arr <= 0.3, np.isclose(0.3, arr))]
>>> array([0., 0.1, 0.2, 0.3])
在这种情况下,这可能不是最好的选择,但它可能有助于了解该功能。
旁注: 如果没有人向你解释过,为什么会发生这种情况。基本上,计算机将所有内容保存为二进制文件,但0.1是二进制的周期数,这意味着计算机无法保存所有数字(因为数量无限多)。十进制等效是:
1/3 + 1/3 + 1/3 = 0.33333 0.33333 + 0.33333 + = 0.99999
这是不是1
嗯......'改编[编曲。 round(1)<= 0.3]'... –
所以我应该在执行任何比较之前总是*整数? – Xiphias
花车之间的等价性总是有风险的事情来测试。 –