为啥在 numpy `nan == nan` 中是 False 而 [nan] 中的 nan 是 True?
Posted
技术标签:
【中文标题】为啥在 numpy `nan == nan` 中是 False 而 [nan] 中的 nan 是 True?【英文标题】:Why in numpy `nan == nan` is False while nan in [nan] is True?为什么在 numpy `nan == nan` 中是 False 而 [nan] 中的 nan 是 True? 【发布时间】:2013-12-17 16:08:40 【问题描述】:虽然问题的第一部分(在标题中)之前已经回答过几次(即Why is NaN not equal to NaN?),但我不明白为什么第二部分会这样工作(受此启发问题How to Check list containing NaN)?
即:
>> nan == nan
False
>> nan in [nan]
True
考虑到@DSM 的答案的问题的解释性附录。那么,为什么float("nan")
的行为与nan
不同?它不应该再次评估为简单的nan
,为什么解释器会这样?
>> x = float("nan")
>> y = nan
>> x
nan
>> y
nan
>> x is nan, x is float("nan"), y is nan
(False, False, True)
基本上,它在第一种情况下引用相同的通用nan
,但在第二种情况下创建单独的对象:
>> nans = [nan for i in range(2)]
>> map(id, nans)
[190459300, 190459300]
>> nans = [float("nan") for i in range(2)]
>> map(id, nans)
[190459300, 190459301]
【问题讨论】:
补充说明,float('nan')
总是创建一个新对象。您正在测试的 nan
是一个预先存在的对象,它永远不会与新创建的对象具有相同的 ID。 Python 中的赋值总是简单地引用原始对象;无论b
是什么,a = b; a is b
将始终返回 True
。
【参考方案1】:
nan
不等于 nan
是 nan
定义的一部分,所以这部分很简单。
至于nan in [nan]
为真,那是因为在列表中包含相等性之前测试了身份。您正在比较相同的两个对象。
如果你用两个不同 nan
s 尝试同样的事情,你会得到 False:
>>> nans = [float("nan") for i in range(2)]
>>> map(id, nans)
[190459300, 190459284]
>>> nans
[nan, nan]
>>> nans[0] is nans[1]
False
>>> nans[0] in nans
True
>>> nans[0] in nans[1:]
False
您的附录与nan
没有太大关系,这就是 Python 的工作原理。一旦您了解 float("nan")
没有义务返回一些 nan 单例,并且 y = x
不会复制 x
而是将名称 y
绑定到由 x
命名的对象,就有什么都没有了。
【讨论】:
嗯...为什么第一个例子中的nan是一样的?为什么不将它们初始化为两个不同的对象?因为x = nan
和nan in [x]
仍然返回True
。
@sashkello:你指的第一个例子是什么?你的nan == nan
? nan
命名一个特定对象(在这种情况下,我很确定它是 np.nan
)。不管你说多少次这个名字,它仍然指向同一个对象:没有初始化。类似地,x = nan
不会复制nan
,它只是将x
命名为一个新名称,并说它命名了同样由nan
命名的对象。例如,在这样做之后尝试x is nan
。
我只是看不出这与 float("nan") 有什么不同呢? nan有不同的“味道”吗?否则,据我了解, float("nan") 仍应返回 nan ,它又是一个相同的对象,不是吗?我想了解为什么nan in [nan]
与 [float("nan")] 中的 `nan 不同?解释器如何知道列表中的 nan 是通过不同的方式获得的?我也不明白为什么 [float("nan")] 中的 float("nan") 在这种情况下是错误的......
不,正如我在原始问题中所说,nans 不是唯一的对象。看上面的文字记录:两个nan
s有不同的id,nans[0] is nans[1]
是False。 nan in [nan]
是 True,因为它基本上是 any(x is nan or x == nan for x in [nan])
。 x is nan
是 True,所以 x == nan
是 False 并不重要。应用于nan in [float("nan")]
的相同规则给出x is nan
为假(它们是不同的对象)并且x == nan
仍然为假。 float("nan") in [float("nan")]
给出 False 因为他们是两个独立的 NANS。
@sashkello,这并不重要,但实际上有 种不同风格的 NaN,也有信号 NaN,它们的行为相同。以上是关于为啥在 numpy `nan == nan` 中是 False 而 [nan] 中的 nan 是 True?的主要内容,如果未能解决你的问题,请参考以下文章
为啥 itertools.groupby 可以将 NaN 分组在列表中而不是 numpy 数组中
在 numpy 数组求和中将 nan 视为零,但所有数组中的 nan 除外
为啥我的输出总是以 NaN 的形式出现,我期待输出作为我的系列数据?
从 pandas 转换为 numpy 后,如果数组包含 nan,则删除“nan”或减少 numpy 数组的长度 [重复]