【问题标题】:Python numpy.nan and logical functions: wrong resultsPython numpy.nan 和逻辑函数:错误的结果
【发布时间】:2013-06-20 19:58:19
【问题描述】:

我在尝试评估时得到了一些令人惊讶的结果 可能包含 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

同样适用于or

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 值?

【问题讨论】:

  • 在旁注中,您想要的对于numpy 当前的工作方式没有多大意义。 NaN 是一个纯浮点值。布尔数组不能容纳 NaNs。因此,有一个逻辑比较返回 NaN 基本上会破坏一切。为了解决这个问题,引入了一个特殊的np.na(不同于np.nan)值,并且已被暂时删除。它可以满足您的需求:github.com/numpy/numpy.org/blob/master/NA-overview.rst
  • @JoeKington 感谢您的评论。很高兴知道,不幸的是,在这种情况下,我必须使用返回 nan 值的第三方模块的结果,所以我没有太多选择。
  • 这完全违反直觉,并导致意想不到的结果......真是麻烦
  • Fwiw 在我的情况下,我用df['value'].shift(-1).fillna(100)<0 搞砸了它

标签: python python-2.7 numpy boolean nan


【解决方案1】:

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

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

nan and True 中,由于nan 为True,并且由于AND 运算符,python 现在将评估第二个表达式并返回第二个表达式的值。所以,在这里你会得到TRUE 作为输出。应用于True and nan 时的逻辑相同,您可以期望nan 作为输出。

OR 运算符中,如果我们查看第一个表达式就足够了,因此“True or nan 将返回 True

【讨论】:

  • ..这解释了我期望得到的结果..例如nan 或 True 应该返回 True(如果 nan 被视为 True),而不是 nan..
  • 因为 nan 是 True,python 将返回 nan 本身(不是 True)例如,“2 或 True”将返回 2(因为 2 为 True),同样“0 或 3”将返回 3(因为0 被认为是 False)。 "2 and 3" 将返回 3 。 "2 and True" 将返回 True
  • orand 短路:docs.python.org/2/library/…
  • @Nakamura nan == True 和 nan is True 虽然评估为 False .. nan == False 和 nan 都是 False。 nan 既不是 False 也不是 True,这就是为什么我认为这种行为是错误的。
  • 首先,包含 and,or 等布尔运算符的 python 表达式的输出不必是布尔值(TrueFalse),这在指向的链接中很好地提到通过@Zhenya。例如,表达式[] or 2 的输出将是2。其次,numpy.nan 指的是“非数字”(docs.scipy.org/doc/numpy/reference/generated/numpy.isnan.html),因此它不等于布尔 True 或布尔 False 运算符。从第一点,我们可以推断出python表达式nan and True的输出是True,而nan and 2的输出是`2'
【解决方案2】:

您可以使用来自 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)

编辑:内置布尔运算符略有不同。 From the docsx and y 等价于 if x is false, then x, else y。因此,如果第一个参数的计算结果为 False,它们将返回它(不是它的布尔等价物,因为它是)。因此:

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

【讨论】:

  • 你期望它基于什么理由?
  • 因为“和”要求两个值都为真。如果其中一个是未知的,您根本无法确定值.. 结果也是未知的..
  • np.bool(np.nan) 计算结果为 True。从那时起,一切都是一致的。
  • 如果你想要一个具有三个值的类型,真、假和'不知道',看看boost::tribool:boost.org/doc/libs/1_53_0/doc/html/tribool.html跨度>
  • boost 不是 cpp 库吗?无论如何,这很容易.. and 可以重新定义为 min 函数,分别为 0、nan 和 1 提供键 -1,0,1。使用相同的键 or 实现为 max.
猜你喜欢
  • 1970-01-01
  • 2017-05-08
  • 2015-09-28
  • 2012-01-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-09
  • 2015-06-01
相关资源
最近更新 更多