我对以下行为感到惊讶:
>>> import numpy as np
>>> from collections import Counter
>>> my_list = [1,2,2, np.nan, np.nan]
>>> Counter(my_list)
Counter({nan: 2, 2: 2, 1: 1}) # Counter treats np.nan as equal and
# tells me that I have two of them
>>> np.nan == np.nan # However, np.nan's are not equal
False
这里发生了什么?
当我使用float('nan')
代替np.nan
时,我得到了我期望的行为:
>>> my_list = [1,2,2, float('nan'), float('nan')]
>>> Counter(my_list)
Counter({2: 2, nan: 1, 1: 1, nan: 1}) # two different nan's
>>> float('nan') == float('nan')
False
我正在使用python 2.7.3
和numpy 1.8.1
。
编辑:
如果我这样做:
>>> a = 300
>>> b = 300
>>> a is b
False
>>> Counter([a, b])
Counter({300: 2})
因此,Counter
或任何python dict
认为两个对象X
和Y
在以下情况下不一样:
X == Y -> False
and
X is Y -> False
正确?
答案 0 :(得分:8)
这不是关于numpy.nan
与float("nan")
的关系,而是你有两个独立的浮动禁令。
>>> np.nan is np.nan
True
>>> float("nan") is float("nan")
False
等等
>>> Counter([1,2,2, np.nan, np.nan])
Counter({nan: 2, 2: 2, 1: 1})
>>> Counter([1,2,2, float("nan"), float("nan")])
Counter({2: 2, nan: 1, 1: 1, nan: 1})
但
>>> f = float("nan")
>>> Counter([1,2,2, f, f])
Counter({nan: 2, 2: 2, 1: 1})
答案 1 :(得分:4)
Python dicts(以及扩展名为Counter
子类)通常基于密钥的==
等式进行比较。 BUT 他们会进行优化,假设x is y
然后是x == y
。只有当x is not y
dict将通过平等回归到比较时。对于大多数类型,x is y
隐含x == y
。它基本上只是浮动的NaNs和故意设计的反例来打破这种情况。