TLDR: is-comparison可以与Python bool
一起使用,而不能与numpy bool_
一起使用。还有其他区别吗?
几天前,我遇到了布尔值的一种奇怪行为。当我尝试对这个numpy数组使用is-comparison时:
arr1 = np.array([1,0,2,0], dtype=bool)
arr1
Out[...]: array([ True, False, True, False])
(这些变量名基于虚构,与真实变量名或生产代码的任何相似之处纯属巧合)
我看到了这个结果:
arr1 is True
Out[...]: False
这是合乎逻辑的,因为arr1
不是True或False,它是numpy数组。我检查了这个:
arr1 == True
Out[...]: array([ True, False, True, False])
这按预期工作。我提到了这种可爱的行为,并立即忘记了。第二天,我检查了数组元素的真实性:
[elem is False for elem in arr1]
它会把这个还给我!
Out[...]: [False, False, False, False]
我真的很困惑,因为我想起了Python数组中的问题(我认为问题出在数组行为中):
arr2 = [True, False, True, False]
[elem is False for elem in arr2]
有效:
Out[...]: [False, True, False, True]
此外,它正在我的另一个numpy数组中工作:
very_cunning_arr = np.array([1, False, 2, False, []])
[elem is False for elem in very_cunning_arr]
Out[...]: [False, True, False, True, False]
当我进入数组时,我发现very_cunning_arr
是由numpy.object
构造的,因为有两个非数字元素,所以它包含Python bool,而arr1
是由{{ 1}}。所以我检查了他们的行为:
numpy.bool_
numpy_waka = np.bool_(True)
numpy_waka
Out[...]: True
python_waka = True
python_waka
Out[...]: True
我终于找到了区别:
[numpy_waka is True, python_waka is True]
毕竟,我有两个问题:
Out[...]: [False, True]
和numpy.bool_
的共同行为是否还有其他差异? (我知道bool
有许多numpy函数和参数,例如numpy.bool_
等)(PS:是的,现在,我知道用.T
与True / False进行比较是不好的):
请勿使用==将布尔值与True或False进行比较。
is
Yes: if greeting:
No: if greeting == True:
Worse: if greeting is True:
编辑1:如another question中所述,numpy具有自己的
类型。但是,这个问题的细节有些不同:我发现is语句的工作原理有所不同,但是在出现这种差异之前-bool_
和bool_
的共同行为是否还有其他不同?如果是,那到底是什么?
答案 0 :(得分:2)
变量存在一些混淆,正在发生的是模块与python之间的“混淆”,请使用isinstance(variable, type)
检查在代码中是否可用。
将单个变量创建为bool变量可以很好地工作,python正确地对其进行了修饰:
np_bool = np.bool(True)
py_bool = True
print(isinstance(np_bool, bool)) # True
print(isinstance(py_bool, bool)) # True
但是与列表不同,numpy bool列表不是列表中的bool值,如本例所示:
# Regular list of int
arr0 = [-2, -1, 0, 1, 2]
# Python list of bool
arr1 = [True, False, True, False]
# Numpy list of bool, from int / bool
arr3_a = np.array([-2, -1, 0, 1, 2], dtype=bool)
arr3_b = np.array([True, False, True, False], dtype=bool)
print(isinstance(arr0[0], int)) # True
print(isinstance(arr1[0], bool)) # True
print(isinstance(arr3_a[0], bool)) # False
print(isinstance(arr3_b[0], bool)) # False
要使用numpy列表中的变量,需要使用bool()
arr3_a = np.array([-2, -1, 0, 1, 2], dtype=bool)
x = (bool(arr3_a[0]) is True)
print(isinstance(x, bool)) # True
快速使用示例:
arr3_a = np.array([-2, -1, 0, 1, 2], dtype=bool)
for c in range(0, len(arr3_a)):
if ( bool(arr3_a[c]) == True ):
print(("List value {} is True").format(c))
else:
print(("List value {} is False").format(c))
答案 1 :(得分:2)
{
'cam': 'CA Manager',
'control_account': 'W80.11.11.01.LL',
'risk_mitigation_scope': 'No',
'statement_of_work': 'For setup and maintainance of of the W80 EVMS Tools',
'wp_manager': 'cohagan1',
'wp_title': 'EVMS Tools',
'wp_type': 'Discrete'
}
注意dtype。使用object dtype,数组的元素是Python对象,就像它们在源列表中一样。
在第一种情况下,数组dtype为布尔值。元素表示布尔值,但它们本身不是Python In [119]: np.array([1,0,2,0],dtype=bool)
Out[119]: array([ True, False, True, False])
In [120]: np.array([1, False, 2, False, []])
Out[120]: array([1, False, 2, False, list([])], dtype=object)
对象。严格来说,True/False
不是Out[119]
contain
个对象。 np.bool_
的类型为Out[119][1]
,但这是“取消装箱”的结果。这是bool_
索引在您请求元素时产生的结果。 (此“拆箱”区别适用于所有非对象dtypes。)
通常,我们不创建ndarray
对象,而是选择dtype
,而是按照您的示例进行操作:
np.array(True)
In [124]: np.bool_(True)
Out[124]: True
In [125]: type(np.bool_(True))
Out[125]: numpy.bool_
In [126]: np.bool_(True) is True
Out[126]: False
In [127]: type(True)
Out[127]: bool
是一个严格的测试,不仅用于平等,而且用于身份。不同类的对象不满足is
测试。对象可以满足is
测试,而不能满足==
测试。
让我们玩一下对象dtype数组:
is
在In [129]: np.array([1, False, 2, np.bool_(False), []])
Out[129]: array([1, False, 2, False, list([])], dtype=object)
In [130]: [i is False for i in _]
Out[130]: [False, True, False, False, False]
显示中,两个Out[129]
对象显示相同,但是False
测试表明它们不同。
专注于您的问题。
Out[130]
是唯一的对象,但与np.bool_(False)
不同。正如您所注意到的,它具有与False
相同的许多属性/方法。
如果数组dtype为np.array(False)
,则它不包含Python bool
对象。它甚至不包含bool
个对象。但是,为这样的数组建立索引将产生一个np.bool_
。然后将bool_
应用于它会产生一个Python item()
。
如果数组对象是dtype,则除非您已采取特殊步骤包括bool
对象,否则它很可能包含Python bool
。
答案 2 :(得分:0)
另一个区别是可以在 np.bool 上自动转换为整数,但不能在 np.bool_ 上完成。
这是需要的,例如here
>>> np.bool(False) - np.bool(True)
-1
>>> np.bool_(False) - np.bool_(True)
TypeError: numpy boolean subtract, the `-` operator, is not supported, use the bitwise_xor, the `^` operator, or the logical_xor function instead.