Python numpy.nan和逻辑函数:错误的结果

Python numpy.nan和逻辑函数:错误的结果,python,python-2.7,numpy,boolean,nan,Python,Python 2.7,Numpy,Boolean,Nan,在尝试评估时,我得到了一些令人惊讶的结果 可能包含nan值的数据上的逻辑表达式(如numpy中的定义) 我想了解为什么会出现这种结果 以及如何实施正确的方法 我不明白的是,为什么这些表达式的计算结果与它们的值相同: from numpy import nan nan and True >>> True # this is wrong.. I would expect to evaluate to nan True and nan >>> nan # OK

在尝试评估时,我得到了一些令人惊讶的结果 可能包含
nan
值的数据上的逻辑表达式(如numpy中的定义)

我想了解为什么会出现这种结果 以及如何实施正确的方法

我不明白的是,为什么这些表达式的计算结果与它们的值相同:

from numpy import nan

nan and True
>>> True
# this is wrong.. I would expect to evaluate to nan

True and nan
>>> nan
# OK

nan and False
>>> False
# OK regardless the value of the first element 
# the expression should evaluate to False

False and nan
>>> False
#ok
类似地,对于

True or nan
>>> True #OK

nan or True
>>> nan #wrong the expression is True

False or nan
>>> nan #OK

nan or False
>>> nan #OK

如何(以有效的方式)实现正确的布尔函数,同时处理
nan
值?

在计算包含
的逻辑表达式时,我们必须计算
运算符两侧的表达式。而对于
运算符,如果第一个表达式为真,则无需检查第二个表达式的正确性

例如,在计算表达式
2>2和3==3
时,首先我们应该检查第一个表达式
2>2
是否为真。如果第一个表达式为False,则无需检查第二个表达式,因为有
运算符,这样一个表达式的结果将为False,因为第一个表达式为False。然而,如果表达式是
2==2和3==3
,那么由于第一个表达式
2==2
为真,那么我们不需要检查第二个表达式的正确性,因为这里第二个表达式也是真的,所以我们得到真作为输出

nan和True
中,由于
nan
为True,并且由于
运算符,python现在将计算第二个表达式并返回第二个表达式的值。因此,这里您将得到
TRUE
作为输出。当应用于
True和nan
时,您可以期望
nan
作为输出


运算符中,查看第一个表达式就足够了,因此“
True或nan
将返回True

您可以使用
numpy
命名空间中的谓词:

>>> np.logical_and(True, np.nan), np.logical_and(False, np.nan)
(True, False)
>>> np.logical_and(np.nan, True), np.logical_and(np.nan, False)
(True, False)
>>>
>>> np.logical_or(True, np.nan), np.logical_or(False, np.nan)
(True, True)
>>> np.logical_or(np.nan, True), np.logical_or(np.nan, False)
(True, True)
编辑:内置布尔运算符略有不同:
x和y
相当于
如果x为false,则x,否则y
。因此,如果第一个参数的计算结果为
false
,则返回它(不是它的布尔等价物)。因此:

>>> (None and True) is None
True
>>> [] and True
[]
>>> [] and False
[]
>>> 

etc

。这解释了我希望得到的结果。例如,nan或True应该返回True(如果nan被视为True),而不是nan。由于nan为True,python将返回nan本身(非True),例如,“2或True”将返回2(因为2为True),同样,“0或3”将返回3(因为0被视为False)。“2和3“将返回3。“2和True”将返回Trueboth
短路:@Nakamura both nan==True和nan is True尽管计算为False。。所以做nan==False,nan是False。nan既不为假也不为真,这就是为什么我认为该行为是错误的。首先,包含布尔运算符(如
的python表达式的输出不必是布尔(
)的,@Zhenya指出的链接中很好地提到了这一点。例如,表达式
[]或2
的输出将是
2
。其次,numpy.nan指的是“非数字”(),因此它既不等于布尔真运算符,也不等于布尔假运算符。从第一点,我们可以推断python表达式
nan和True
的输出将是
True
,其中
nan和2
的输出将是'2',您希望它是基于什么理由的?因为“and”要求两个值都为True。。如果其中一个未知,则无法确定其值。。结果也是未知的。
np.bool(np.nan)
的计算结果为
True
。从那一点开始,一切都是一致的。如果你想要一个有三个值的类型,true、false和“不知道”,看看
boost::tribool
:boost不是cpp库吗?无论如何,这很容易。。
可以重新定义为min函数,分别为0、nan和1提供键-1,0,1。使用相同的键
实现为max。在旁注中,您想要的东西与当前的
numpy
工作方式没有多大意义
NaN
是一个纯浮点值。布尔数组不能容纳
NaN
s。因此,使用逻辑比较返回值
NaN
基本上会破坏一切。为了解决这个问题,引入了一个特殊的
np.na
(不同于
np.nan
)值,并暂时删除了该值。它能满足你的需求:见@JoeKington谢谢你的评论。很高兴知道,不幸的是,在这种情况下,我不得不使用第三方模块返回nan值的结果,所以我没有太多选择。这完全违反直觉,导致意外的结果。。。在我的例子中,我用
df['value'].shift(-1).fillna(100)将它填充起来,这真是太麻烦了