**TLDR:**is-comparison适用于Python bool
,不适用于numpy bool_
。是否存在其他差异?
几天前我遇到了一个奇怪的布尔行为。当我试图对这个numpy数组使用is比较时:
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布尔值,而arr1
是由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.bool_
有许多numpy函数和参数,如.T
和其他)
1.如何检查numpy数组是否只包含numpy布尔值,而不包含Python布尔值?
(PS:是的,现在我知道用is
比较True/False是不好的):
不要使用==将布尔值与True或False进行比较。
Yes: if greeting:
No: if greeting == True:
Worse: if greeting is True:
**Edit 1:**正如在another question中提到的,numpy有自己的bool_
类型,但是这个问题的细节有点不同:我发现is-statements的工作方式不同,但在此之前,bool_
和bool
的共同行为是否有其他不同之处?如果有,具体是什么?
4条答案
按热度按时间mxg2im7a1#
注意dtype。对于对象dtype,数组的元素是Python对象,就像它们在源列表中一样。
在第一种情况下,数组的dtype是布尔型的。元素代表布尔值,但它们本身不是Python
True/False
对象。严格地说,Out[119]
不是contain
np.bool_
对象。Out[119][1]
是bool_
类型。但这是'unboxing'的结果。它是ndarray
索引在您请求一个元素时产生的结果。(这种'unboxing'的区别对所有非对象数据类型都是正确的。)通常我们不创建
dtype
对象,而更喜欢np.array(True)
,但要遵循您的示例:is
是一个严格的测试,不仅是对相等性的测试,还对同一性的测试。不同类的对象不满足is
测试。对象可以满足==
测试,但不满足is
测试。让我们来看看对象dtype数组:
在
Out[129]
显示中,两个False
对象显示相同,但Out[130]
测试显示它们不同。专注于你的问题。
np.bool_(False)
是一个独特的对象,但与False
不同。正如您所注意到的,它有许多与np.array(False)
相同的属性/方法。bool
,它就不包含Pythonbool
对象,甚至不包含np.bool_
对象,然而索引这样的数组会产生bool_
,而将item()
应用于它会产生Pythonbool
。bool
,除非你已经采取了特殊的步骤来包含bool_
对象。5gfr0r5j2#
变量有些混乱,发生的是模块和python之间的“混乱”,使用
isinstance(variable, type)
检查它是什么,如果在你的代码中可用。创建一个bool变量就可以了,python会正确地读取它:
但是对于列表,情况就不同了,numpy bool列表并不是列表上的bool值,正如你在这个例子中看到的:
为了使用numpy列表中的变量,需要使用
bool()
进行转换快速使用示例:
r8uurelv3#
另一个区别是可以在np.bool上自动强制转换为整数,但不能在np.bool_上。
这是必需的,例如here
slmsl1lt4#
备忘录
测试1:
假假真假
假假假真
测试2:
真真真真
测试3:
假假假真
测试4:
对对错错
测试_5:
假真