標題有點誤導,因爲它不完全是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
花車之間的等價性總是有風險的事情來測試。 –