far*_*rth 6 python types numpy
我正在玩比较两个不同阵列的数据类型,以选择一个适合两者的组合.我很高兴发现我可以执行比较操作,但在此过程中发现了以下奇怪的行为:
In [1]: numpy.int16 > numpy.float32
Out[1]: True
In [2]: numpy.dtype('int16') > numpy.dtype('float32')
Out[2]: False
Run Code Online (Sandbox Code Playgroud)
谁能解释一下这里发生了什么?这是NumPy 1.8.2.
第一个比较没有意义,第二个比较有意义。
随着numpy.int16 > numpy.float32我们比较两个type对象:
>>> type(numpy.int16)
type
>>> numpy.int16 > numpy.float32 # I'm using Python 3
TypeError: unorderable types: type() > type()
Run Code Online (Sandbox Code Playgroud)
在 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
Run Code Online (Sandbox Code Playgroud)
这个排序背后的逻辑是什么?
dtype实例根据一个实例是否可以(安全地)转换为另一个实例进行排序。如果可以安全地强制转换为该类型,则一种类型小于另一种类型。
对于比较运算符的实现,请查看descriptor.c;特别是在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;
Run Code Online (Sandbox Code Playgroud)
本质上,NumPy 只是检查这两种类型是否 (i) 不等价,以及 (ii) 第一种类型可以转换为第二种类型。
此功能也在 NumPy API 中公开为np.can_cast:
>>> np.can_cast('int32', '|S10')
False
>>> np.can_cast('int32', '|S11')
True
Run Code Online (Sandbox Code Playgroud)