numpy 这些np dtypes之间的区别

oo7oh9g9  于 2023-10-19  发布在  其他
关注(0)|答案(1)|浏览(158)

我有两个关于numpy dtypes的问题:
(1)我注意到下面的numpy数据集比较相等但不相同:

np.str_ == np.dtype('U') # true
id(np.str_) == id(np.dtype('U'))

这些类型之间有什么区别吗?或者这些只是指定同一类型的不同方法?
(2):
如果我指定以下内容:

a = np.array([1,2,3],dtype='d')
b = np.array([1,2,3],dtype='g')

然后我得到相同的数组dtype

a.dtype
dtype('float64')
b.dtype
dtype('float64')

但各个元素是不同的:

type(a[0])
<class 'numpy.float64'>
type(b[0])
<class 'numpy.longdouble'>

我的问题是:这些单独的元素类型之间的确切区别是什么?为什么它们Map到相同的数组类型?

gcuhipw9

gcuhipw91#

关于Float:

In [174]: a = np.array([1.32,23.01,3],dtype='d')    
In [175]: b = np.array([1.32,23.01,3],dtype='g')

底层的数据缓冲区是相同的-将它们视为字节:

In [176]: a.view('u1')
Out[176]: 
array([ 31, 133, 235,  81, 184,  30, 245,  63, 195, 245,  40,  92, 143,
         2,  55,  64,   0,   0,   0,   0,   0,   0,   8,  64], dtype=uint8)

In [177]: b.view('u1')
Out[177]: 
array([ 31, 133, 235,  81, 184,  30, 245,  63, 195, 245,  40,  92, 143,
         2,  55,  64,   0,   0,   0,   0,   0,   0,   8,  64], dtype=uint8)

In [178]: a.dtype, b.dtype
Out[178]: (dtype('float64'), dtype('float64'))

在我的机器上(常规Windows 11),longdoubledouble相同;它不支持float96float128
虽然list包含对python对象的引用,但numpy数组有一个'raw' c字节数组。a[0]不会返回该数组中的对象。它返回一个新的python对象,一个numpy scalar,其类型由dtype确定,并且值是从数组中“复制”的。这种unboxing比列表索引更复杂,也更慢。

In [179]: a[0], b[0]
Out[179]: (1.32, 1.32)    
In [180]: type(a[0]), type(b[0])
Out[180]: (numpy.float64, numpy.longdouble)

在这些类型下面有一个复杂的类继承树

In [193]: type(a[0]).__mro__
Out[193]: 
(numpy.float64,
 numpy.floating,
 numpy.inexact,
 numpy.number,
 numpy.generic,
 float,
 object)

In [194]: type(b[0]).__mro__
Out[194]: 
(numpy.longdouble,
 numpy.floating,
 numpy.inexact,
 numpy.number,
 numpy.generic,
 object)

正如scalars页面上所记录的,有很多aliases

相关问题