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)将它填充起来,这真是太麻烦了