NumPy 数据类型比较
NumPy data type comparison
我正在尝试比较两个不同数组的数据类型,以选择一个适合组合两者的数组。我很高兴地发现我可以执行比较操作,但在这个过程中发现了以下奇怪的行为:
In [1]: numpy.int16 > numpy.float32
Out[1]: True
In [2]: numpy.dtype('int16') > numpy.dtype('float32')
Out[2]: False
谁能解释一下这是怎么回事?这是 NumPy 1.8.2.
没什么意思。 Python 2 尝试为未定义如何相互比较的对象提供一致但无意义的比较结果。开发人员认为这是一个错误,在 Python 3 中,这些比较将引发 TypeError
.
第一个比较没有意义,第二个有意义。
对于 numpy.int16 > numpy.float32
我们正在比较两个 type
对象:
>>> type(numpy.int16)
type
>>> numpy.int16 > numpy.float32 # I'm using Python 3
TypeError: unorderable types: type() > type()
在 Python 3 中,此比较立即失败,因为没有为 type
实例定义顺序。在 Python 2 中,返回了一个布尔值,但不能依赖其一致性(它回退到比较内存地址或其他实现级别的东西)。
第二个比较 在 Python 3 中起作用,并且它始终如一地起作用(在 Python 2 中相同)。这是因为我们现在正在比较 dtype
个实例:
>>> type(numpy.dtype('int16'))
numpy.dtype
>>> numpy.dtype('int16') > numpy.dtype('float32')
False
>>> numpy.dtype('int32') < numpy.dtype('|S10')
False
>>> numpy.dtype('int32') < numpy.dtype('|S11')
True
这个顺序背后的逻辑是什么?
dtype
个实例根据一个实例是否可以(安全地)转换为另一个实例来排序。一种类型小于另一种类型,如果它可以安全地转换到那种类型。
比较运算符的实现,参见descriptor.c; specifically at the arraydescr_richcompare
函数。
这是 <
运算符映射到的内容:
switch (cmp_op) {
case Py_LT:
if (!PyArray_EquivTypes(self, new) && PyArray_CanCastTo(self, new)) {
result = Py_True;
}
else {
result = Py_False;
}
break;
本质上,NumPy 只是检查这两种类型 (i) 不等价,以及 (ii) 第一种类型可以转换为第二种类型。
此功能也在 NumPy API 中公开为 np.can_cast
:
>>> np.can_cast('int32', '|S10')
False
>>> np.can_cast('int32', '|S11')
True
我正在尝试比较两个不同数组的数据类型,以选择一个适合组合两者的数组。我很高兴地发现我可以执行比较操作,但在这个过程中发现了以下奇怪的行为:
In [1]: numpy.int16 > numpy.float32
Out[1]: True
In [2]: numpy.dtype('int16') > numpy.dtype('float32')
Out[2]: False
谁能解释一下这是怎么回事?这是 NumPy 1.8.2.
没什么意思。 Python 2 尝试为未定义如何相互比较的对象提供一致但无意义的比较结果。开发人员认为这是一个错误,在 Python 3 中,这些比较将引发 TypeError
.
第一个比较没有意义,第二个有意义。
对于 numpy.int16 > numpy.float32
我们正在比较两个 type
对象:
>>> type(numpy.int16)
type
>>> numpy.int16 > numpy.float32 # I'm using Python 3
TypeError: unorderable types: type() > type()
在 Python 3 中,此比较立即失败,因为没有为 type
实例定义顺序。在 Python 2 中,返回了一个布尔值,但不能依赖其一致性(它回退到比较内存地址或其他实现级别的东西)。
第二个比较 在 Python 3 中起作用,并且它始终如一地起作用(在 Python 2 中相同)。这是因为我们现在正在比较 dtype
个实例:
>>> type(numpy.dtype('int16'))
numpy.dtype
>>> numpy.dtype('int16') > numpy.dtype('float32')
False
>>> numpy.dtype('int32') < numpy.dtype('|S10')
False
>>> numpy.dtype('int32') < numpy.dtype('|S11')
True
这个顺序背后的逻辑是什么?
dtype
个实例根据一个实例是否可以(安全地)转换为另一个实例来排序。一种类型小于另一种类型,如果它可以安全地转换到那种类型。
比较运算符的实现,参见descriptor.c; specifically at the arraydescr_richcompare
函数。
这是 <
运算符映射到的内容:
switch (cmp_op) {
case Py_LT:
if (!PyArray_EquivTypes(self, new) && PyArray_CanCastTo(self, new)) {
result = Py_True;
}
else {
result = Py_False;
}
break;
本质上,NumPy 只是检查这两种类型 (i) 不等价,以及 (ii) 第一种类型可以转换为第二种类型。
此功能也在 NumPy API 中公开为 np.can_cast
:
>>> np.can_cast('int32', '|S10')
False
>>> np.can_cast('int32', '|S11')
True