天天看點

比較NaN和數字

作者:老齊

先看下面的代碼,有何感悟?

>>> import numpy as np
>>> min(2, np.nan)
2
>>> min(np.nan, 2)
nan           

複制

是不是有點意思?

怎麼解釋?

首先要了解Python中的

min

函數,根據它的官方文檔,有這樣一句話:If multiple items are minimal, the function returns the first one encountered.

意思是說,

min

函數會傳回它所遇到的第一個最小的項——難道說最小項還可能有多個嗎?完全有可能。不過,還是要用更啰嗦的話把

min

的工作流程說一下,雖然文檔中沒有說。它可能是從第一項開始循環,如果某項比它小,那麼目前最小的就是此項了,依次向後循環,直到最後。例如:

[3, 4, 1, 1]

  1. 3

    是最小項,向後循環,3<4,傳回True,則最小項還是3;
  2. 再循環,3<1,傳回False,最小項就是1。
  3. 繼續循環,後面的1不比3小,那麼就傳回前面那個1——當然,在這裡事實上兩個1是同一個對象了。這裡僅僅是用此示例說明

    min

    函數的工作流程罷了。

了解了

min

的工作過程之後,再來看

np.nan

,它是Python中表示缺失值的符号,并且,注意,它是浮點數類型。

>>> type(np.nan)
<class 'float'>           

複制

是以,我們在資料科學中,會用它表示缺失值,這樣做不影響運算——請參考《資料準備和特征工程》中詳細介紹。

在Python規定,

np.nan

與數字比較,都會傳回

False

,也就是說它既比任何數字大,又比任何數字小。

>>> 1 > np.nan
False
>>> np.nan > 1
False
>>> 1 < np.nan
False
>>> np.nan < 1
False
>>> np.nan == 1
False           

複制

如果在

min

函數的參數清單中第一個是

np.nan

,則它與後面的任何一個數字比較,都會被視為最小值,因為沒有數字會“小于”它。另一方面,如果

np.nan

不在第一個位置,又因為它不“小于”任何數字,那麼,就出現了本文開頭的代碼結果了。

與之類似,還有:

>>> max(2, np.nan)
2
>>> max(np.nan, 2)
nan           

複制

結合上面的闡述,就可以解釋了。