2017-10-20 51 views
2

工作,我注意到一個問題轉換列表NaN值,以集:Python的「設置」操作不numpy.nan

import pandas as pd 
import numpy as np 

x = pd.DataFrame({'a':[None,None]}) 
x_numeric = pd.to_numeric(x['a']) #converts to numpy.float64 
set(x_numeric) 

,應返回{}楠而是返回{囡楠}。但是,這樣做:

set([numpy.nan, numpy.nan]) 

返回預期的{nan}。前者顯然是class numpy.float64,而後者是默認類float。

任何想法,爲什麼設置()不numpy.float64 NaN值工作?我使用Pandas版本0.18和Numpy版本1.10.4。

+1

numpy two nan's are equal。在一個列表中它們可能是相同的,但不是在numpy數組中。要找出try'set(np.array([np.nan,np.nan]))''。在熊貓中,他們的系列將採用numpy數組格式 – Dark

+2

'x_numeric.unique()'只返回'[nan]',這很有趣。 –

+0

嗯我現在困惑了一下。 – Dark

回答

5

的NaN在float64陣列不指向存儲器中的相同的空間np.NaN,(它們,就像陣列中的每個其它數目,陣列中的8個字節)。我們可以看到這個時候我們採取id

In [11]: x_numeric 
Out[11]: 
0 NaN 
1 NaN 
Name: a, dtype: float64 

In [12]: x_numeric.apply(id) 
Out[12]: 
0 4657312584 
1 4657312536 
Name: a, dtype: int64 

In [13]: id(np.nan) 
Out[13]: 4535176264 

In [14]: id(np.nan) 
Out[14]: 4535176264 

這是kindof一個python「疑難雜症」出現這種情況,因爲它是一個優化(檢查設置平等蟒蛇檢查它是否在同一個對象之前:具有相同的id /在內存中的位置):

In [21]: s = set([np.nan]) 

In [22]: np.nan in s 
Out[22]: True 

In [23]: x_numeric.apply(lambda x: x in s) 
Out[23]: 
0 False 
1 False 
Name: a, dtype: bool 

這是一個「疑難雜症」,是因爲NaN的,不像大多數對象不等於自身的原因:

In [24]: np.nan == np.nan 
Out[24]: False 
+0

這是一個非常好的例子值得更多的選票。 – Dark

2

怒江MPY是這裏的紅鯡魚 - np.nan僅僅是float('nan')一個名字,這說明了同樣的問題:

>>> a = float('nan') 
>>> b = float('nan') 
>>> {a, b} 
{nan, nan} 
>>> {a, a} 
{nan} 

安迪說,這是關於建立平等集合成員檢查時x == y之前嘗試x is y