12

在 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()

4

3 回答 3

25

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 < b < c-style 链接工作。

于 2013-06-12T21:10:43.237 回答
10

您可以使用 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)
于 2013-06-12T21:13:56.890 回答
2

numpy 中不允许链式比较。您需要分别编写左右比较,并使用按位运算符将它们链接起来。此外,由于运算符优先级(|&并且^具有更高的优先级) ,您还需要将两个表达式都括起来。在这种情况下,由于您希望同时满足两个条件,因此需要按位 AND ( &):

(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>1,因为具有许多值的布尔数组既不评估为Trueor False。正是由于这种歧义,这是不允许的,并且在布尔上下文中评估数组总是会产生ValueError

于 2020-06-21T13:39:41.040 回答