2014-11-08 40 views
2

我試圖比較包含nan的python中的兩個集合,但由於{float('nan')} != {float('nan')}而苦苦掙扎。例如:在python中比較包含nan的集合

s1 = {float('nan'), 1} 
s2 = {float('nan'), 1, 2} 

assert set.issubset(s1, s2) 

我得到一個斷言錯誤。我該如何處理?

+0

你在s2中左括號??? – Hackaholic 2014-11-08 02:35:46

+0

是的,對不起。固定 – user1507844 2014-11-08 02:37:39

+0

@ user1507844:請說明「我該如何處理這個」的含義。你想要發生什麼? – unutbu 2014-11-08 02:46:15

回答

2

您也可以爲此編寫一個簡單的函數。請注意,float('nan') == float('nan')對於nan是False;要檢查是否有任何元素是nan,我們只需要將其與自身進行比較。

def is_subset(s1, s2): 
    no_nan_set = lambda s: {x for x in s if x == x} 
    s1_nan, s2_nan = no_nan_set(s1), no_nan_set(s2) 
    if s1_nan != s1 and s2_nan != s2: 
     return s1_nan.issubset(s2_nan) 
    elif s1_nan == s1 and s2_nan == s2: 
     return s1.issubset(s2) 
    else: 
     return False 

可以簡化if-elif-else

def is_subset(s1, s2): 
    no_nan_set = lambda s: {x for x in s if x == x} 
    s1_nan, s2_nan = no_nan_set(s1), no_nan_set(s2) 
    return (s1_nan != s1 and s2_nan != s2 and s1_nan.issubset(s2_nan)) \ 
     or (s1_nan == s1 and s2_nan == s2 and s1.issubset(s2)) 

注意,如果只將您所設定的有兩個或兩個以上nan S(因爲float('nan') != float('nan')),這將正常工作,同樣將工作好嗎如果nanid s不同。最後,即使您在一套或兩套中都沒有nan,這也可以工作。

2

刪除所有nan值來創建臨時集,然後對其進行比較。之後,分別處理nan比較。例如,您可以檢查兩個原始集合是否包含nan

即使您可以在沒有聲明異常的情況下執行比較,float('nan') == float('nan')也會返回False,因此從該組比較中獲得的價值很小(這會使比較的其餘部分無效)。您可以通過打印set.issubset來檢查此行爲。

s1 = frozenset({float('nan'), 1}) 
s2 = frozenset({float('nan'), 1, 2}) 
print frozenset.issubset(s1,s2) 

其中打印False

雖然set is deprecated,您可以生成臨時設置如下:

s3 = set([value for value in s1 if not math.isnan(value)]) 

(根據需要重複每個臨時設置)

+0

一旦它已經在集合中,我怎樣才能從集合中刪除nan? – user1507844 2014-11-13 01:00:33

+0

@ user1507844:['sets'已棄用](https://docs.python.org/2/library/sets.html)。但是,如果你不能使用'set.remove'來完成這個,你可以很容易地生成不包含'nan'的新集合,並使用'set.issubset'。例如,'s3 = set([如果不是math.isnan(value)]),將會在s1中生成一個新的'set',其中包含所有不等於'nan'的值。我也編輯了這個評論到我原來的帖子,以防這裏的語法令人困惑。 – grovesNL 2014-11-13 02:23:02

+0

創建一個新的集合可能是最簡單的...只是不知道math.isnan。謝謝! – user1507844 2014-11-13 19:32:28

3

一種方法:身份平等(見文檔here前測試,例如),因此,如果您使用相同nan它會工作:

>>> nan = float("nan") 
>>> s1 = {nan, 1} 
>>> s2 = {nan, 1, 2} 
>>> set.issubset(s1, s2) 
True 

即使

>>> s1 = {float("nan"), 1} 
>>> s2 = {float("nan"), 1, 2} 
>>> set.issubset(s1, s2) 
False 

nan s工作是不夠的尷尬,我會盡量避免將它們放在集和切換到不同的規範形式。但你總是可以確定它是同一個:

>>> def one_nan(x, nan=float("nan")): 
...  return nan if math.isnan(x) else x 
... 
>>> set.issubset(set(map(one_nan, s1)), set(map(one_nan, s2))) 
True 

或千變異。 (我有時使用x != x作爲nan-detection的快捷方式,但在此處可能是個好主意。)

+0

我無法控制它是否在設定中結束或不幸... – user1507844 2014-11-13 01:01:21