【问题标题】:NumPy chained comparison with two predicatesNumPy 与两个谓词的链式比较
【发布时间】:2013-06-09 03:29:20
【问题描述】:

在 NumPy 中,我可以像这样生成一个布尔数组:

>>> arr = np.array([1, 2, 1, 2, 3, 6, 9])
>>> arr > 2
array([False, False, False, False,  True,  True,  True], dtype=bool)

我们如何将比较链接在一起?例如:

>>> 6 > arr > 2
array([False, False, False, False,  True,  False,  False], dtype=bool)

尝试这样做会导致错误消息

ValueError:具有多个元素的数组的真值不明确。使用 a.any() 或 a.all()

【问题讨论】:

  • 仅供参考,PEP 535 建议在 python 3.7 中实现这一点。

标签: python arrays numpy boolean-expression


【解决方案1】:

你能得到的最接近的AFAIK是使用&、|和^:

>>> arr = np.array([1, 2, 1, 2, 3, 6, 9])
>>> (2 < arr) & (arr < 6)
array([False, False, False, False,  True, False, False], dtype=bool)
>>> (2 < arr) | (arr < 6)
array([ True,  True,  True,  True,  True,  True,  True], dtype=bool)
>>> (2 < arr) ^ (arr < 6)
array([ True,  True,  True,  True, False,  True,  True], dtype=bool)

我认为您无法让a &lt; b &lt; c 样式的链接起作用。

【讨论】:

    【解决方案2】:

    您可以使用 numpy 逻辑运算符来做类似的事情。

    >>> arr = np.array([1, 2, 1, 2, 3, 6, 9])
    >>> arr > 2
    array([False, False, False, False,  True,  True,  True], dtype=bool)
    >>>np.logical_and(arr>2,arr<6)
    Out[5]: array([False, False, False, False,  True, False, False], dtype=bool)
    

    【讨论】:

      【解决方案3】:

      numpy 中不允许链式比较。您需要分别编写左右比较,并将它们与bitwise operators 链接起来。由于operator precendence(|、&amp; 和^ 具有更高的优先级),您还需要将这两个表达式都加上括号。在这种情况下,由于您希望同时满足这两个条件,因此您需要按位与 (&amp;):

      (2<arr) & (arr<6)
      # array([False, False, False, False,  True, False, False])
      

      实际上在PEP 535 中建议使这成为可能,尽管它仍然被推迟。其中解释了为什么会发生这种情况。如问题中所述,以这种方式链接比较会产生:

      2<arr<6
      

      ValueError:具有多个元素的数组的真值不明确。 使用 a.any() 或 a.all()

      这里的问题是,python 在内部将上述内容扩展为:

      2<arr and arr<6
      

      这是导致错误的原因,因为and 隐式调用bool,而NumPy 只允许对单个元素(不是带有size&gt;1 的数组)的布尔值进行隐式强制,因为带有许多值既不评估为True 也不评估为False。正是由于这种歧义,这是不允许的,并且在布尔上下文中评估数组总是会产生 ValueError

      【讨论】:

      • 感谢您的更新回答!我希望提案被接受
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-10-10
      • 1970-01-01
      • 2019-09-19
      • 2010-11-13
      • 1970-01-01
      • 2021-09-16
      • 1970-01-01
      相关资源
      最近更新 更多