Numpy:具有多个元素的数组的真值是不明确的

时间:2015-03-06 13:35:58

标签: python numpy

我真的很困惑为什么会出现这个错误。这是我的代码:

import numpy as np

x = np.array([0, 0])
y = np.array([10, 10])
a = np.array([1, 6])
b = np.array([3, 7])
points = [x, y, a, b]
max_pair = [x, y]
other_pairs = [p for p in points if p not in max_pair]
>>>ValueError: The truth value of an array with more than one element is ambiguous. 
Use a.any() or a.all()
(a not in max_paix)
>>>ValueError: The truth ...

令我困惑的是,以下工作正常:

points = [[1, 2], [3, 4], [5, 7]]
max_pair = [[1, 2], [5, 6]]
other_pairs = [p for p in points if p not in max_pair]
>>>[[3, 4], [5, 7]]
([5, 6] not in max_pair)
>>>False

为什么在使用numpy数组时会发生这种情况? not in/in存在歧义吗?
使用any()\all()的正确语法是什么?

2 个答案:

答案 0 :(得分:4)

Numpy数组定义了一个自定义相等运算符,即它们是实现__eq__魔术函数的对象。因此,==运算符和依赖于这种等式的所有其他函数/运算符调用此自定义相等函数。

Numpy的相等性基于数组的元素比较。因此,作为回报,您将获得另一个具有布尔值的numpy数组。例如:

x = np.array([1,2,3])
y = np.array([1,4,5])
x == y

返回

array([ True, False, False], dtype=bool)

但是,in运算符与列表组合需要进行相等比较,只返回单个布尔值。这就是错误要求allany的原因。例如:

any(x==y)

返回True,因为生成的数组中至少有一个值为True。 相比之下

all(x==y) 

返回False,因为结果数组的所有值均为True

因此,在您的情况下,解决问题的方法如下:

other_pairs = [p for p in points if all(any(p!=q) for q in max_pair)]

print other_pairs打印预期结果

[array([1, 6]), array([3, 7])]

为什么这样?好吧,我们从积分中查找 p 项目,其中任何条目不等于所有的条目来自 max_pair 的商品 q

答案 1 :(得分:0)

背后的原因是它们完全是两个不同的对象。 np.array拥有自己的运营商。

它们的名称与全局运算符anyall相同,但不完全相同,这种区别反映在它们是np.array的方法中。

>>> x = np.array([0,9])
>>> x.any(axis=0)
True
>>> y = np.array([10, 10])
>>> y.all()
True
>>> y.all(axis=0)
True

同时

>>> bool([])
False
>>> bool([[]])
True
>>> bool([[]][0])
False

注意第一个结果是假的(在python2中),空列表被视为False。但是,其中包含其他列表的列表,即使该列表为空,也不是False,而是True。评估内部列表会再次返回False,因为它是空的。由于anyall定义为转化为bool,因此您看到的结果不同。

>>> help(all)
all(...)
    all(iterable) -> bool
    Return True if bool(x) is True for all values x in the iterable.

>>> help(any)
any(...)
    any(iterable) -> bool
    Return True if bool(x) is True for any x in the iterable.

查看逻辑numpy运算符的更好解释here