python - Python bool 和 numpy bool_ 的行为究竟有何不同?
问题描述
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 布尔值并且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
和其他) - 如何检查 numpy 数组是否仅包含 numpy 布尔值,而不包含 Pythonic 布尔值?
(PS:是的,现在我知道与 True/False 相比is
是不好的):
不要使用 == 将布尔值与 True 或 False 进行比较。
Yes: if greeting: No: if greeting == True: Worse: if greeting is True:
编辑 1:正如另一个问题中提到的,numpy 有自己的bool_
类型。但是这个问题的细节有点不同:我发现 is-statements 的工作方式不同,但在这种差异之前 - 还有其他一些共同点bool_
和bool
行为不同吗?如果是,具体是什么?
解决方案
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)
注意数据类型。使用 object dtype,数组的元素是 Python 对象,就像它们在源列表中一样。
在第一种情况下,数组 dtype 是布尔值。这些元素表示布尔值,但它们本身不是 PythonTrue/False
对象。严格来说Out[119]
没有contain
np.bool_
对象。 Out[119][1]
是 type bool_
,但这是“拆箱”的结果。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
测试。对象可以满足==
测试而不满足is
测试。
让我们玩一下 object dtype 数组:
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
. 正如您所注意到的,它具有许多与np.array(False)
.如果数组 dtype 是
bool
它不包含 Pythonbool
对象。它甚至不包含np.bool_
对象。然而,索引这样一个数组将产生一个bool_
.item()
反过来应用它会产生一个 Pythonbool
。如果数组对象 dtype,它很可能包含 Python
bool
,除非您已采取特殊步骤来包含bool_
对象。
推荐阅读
- python - 输出层有四个节点,但我想使用其中一个节点的输出,我该如何解决?
- c# - 子类和抽象类上的等于运算符
- wordpress - WordPress 中自定义分类法之间的关系
- node.js - 节点邮件模块的 html 支持
- google-bigquery - 谷歌云存储加入多个 csv 文件
- node.js - 使用 pracrand 测试 RNG 的 nodejs JavaScript 堆内存不足
- python-3.x - 如何从python 3中的字符串数据框中找到出现次数最多的句子
- javascript - Google Drive API 压缩文件损坏
- offline - 离线使用 Cartopy 地图
- python - 在按钮中创建图像