为什么numpy.core.numeric._typelessdata中有两个np.int64(为什么numpy.int64不是numpy.int64?)

Ero*_*mic 11 python numpy

这不是一个好奇心问题.

在我的64位Linux解释器上,我可以执行

In [10]: np.int64 == np.int64
Out[10]: True

In [11]: np.int64 is np.int64
Out[11]: True
Run Code Online (Sandbox Code Playgroud)

太棒了,正是我所期待的.但是我发现了numpy.core.numeric模块的这个奇怪的属性

In [19]: from numpy.core.numeric import _typelessdata

In [20]: _typelessdata
Out[20]: [numpy.int64, numpy.float64, numpy.complex128, numpy.int64]
Run Code Online (Sandbox Code Playgroud)

很奇怪为什么numpy.int64在那里两次?让我们调查一下

In [23]: _typelessdata[0] is _typelessdata[-1]
Out[23]: False
In [24]: _typelessdata[0] == _typelessdata[-1]
Out[24]: False
In [25]: id(_typelessdata[-1])
Out[25]: 139990931572128
In [26]: id(_typelessdata[0])
Out[26]: 139990931572544
In [27]: _typelessdata[-1]
Out[27]: numpy.int64
In [28]: _typelessdata[0]
Out[28]: numpy.int64
Run Code Online (Sandbox Code Playgroud)

哇他们是不同的.这里发生了什么?为什么有两个np.int64?

ali*_*i_m 4

以下_typelessdata是在 中构建的行numeric.py

_typelessdata = [int_, float_, complex_]
if issubclass(intc, int):
    _typelessdata.append(intc)

if issubclass(longlong, int):
    _typelessdata.append(longlong)
Run Code Online (Sandbox Code Playgroud)

intc是一个 C 兼容(32 位)有符号整数,并且int是一个原生 Python 整数,根据平台的不同,它可以是 32 位或 64 位。

  • 在 32 位系统上,本机 Pythonint类型也是 32 位,因此 issubclass(intc, int)返回True并附intc加到_typelessdata,最终看起来像这样:

    [numpy.int32, numpy.float64, numpy.complex128, numpy.int32]
    
    Run Code Online (Sandbox Code Playgroud)

    注意_typelessdata[-1] is numpy.intc,不是numpy.int32

  • 在 64 位系统上,int是 64 位,因此issubclass(longlong, int)返回True并将 alonglong附加到_typelessdata,结果是:

    [numpy.int64, numpy.float64, numpy.complex128, numpy.int64]
    
    Run Code Online (Sandbox Code Playgroud)

    在这种情况下,正如乔指出的那样(_typelessdata[-1] is numpy.longlong) == True


更大的问题是为什么内容_typelessdata要这样设置。我在 numpy 源代码中找到的唯一_typelessdata实际使用的地方是 同一文件中定义中的这一行:np.array_repr

skipdtype = (arr.dtype.type in _typelessdata) and arr.size > 0
Run Code Online (Sandbox Code Playgroud)

的目的_typelessdata是确保正确打印恰好与(平台相关的)本机 Python 整数类型相同的np.array_repr数组的字符串表示形式。dtype

例如,在32位系统上,int32bit在哪里:

In [1]: np.array_repr(np.intc([1]))
Out[1]: 'array([1])'

In [2]: np.array_repr(np.longlong([1]))
Out[2]: 'array([1], dtype=int64)'
Run Code Online (Sandbox Code Playgroud)

而在 64 位系统上,int64 位在哪里:

In [1]: np.array_repr(np.intc([1]))
Out[1]: 'array([1], dtype=int32)'

In [2]: np.array_repr(np.longlong([1]))
Out[2]: 'array([1])'
Run Code Online (Sandbox Code Playgroud)

arr.dtype.type in _typelessdata上面一行中的检查可确保跳过dtype相应平台相关的本机整数的打印dtypes