天天看點

NumPy之:資料類型對象dtype簡介dtype的定義可轉換為dtype的對象

簡介

之前講到了NumPy中有多種資料類型,每種資料類型都是一個dtype(numpy.dtype )對象。今天我們來詳細講解一下dtype對象。

dtype的定義

先看下dtype方法的定義:

class numpy.dtype(obj, align=False, copy=False)      

其作用就是将對象obj轉成dtype類型的對象。

它帶了兩個可選的參數:

  • align – 是否按照C編譯器的結構體輸出格式對齊對象。
  • Copy – 是拷貝對象,還是對對象的引用。

dtype可以用來描述資料的類型(int,float,Python對象等),描述資料的大小,資料的位元組順序(小端或大端)等。

可轉換為dtype的對象

可轉換的obj對象可以有很多種類型,我們一一來進行講解

dtype對象

如果obj對象本身就是一個dtype對象,那麼可以進行無縫轉換。

None

不傳的話,預設就是

float_

,這也是為什麼我們建立數組預設都是float類型的原因。

數組标量類型

内置的數組标量可以被轉換成為相關的data-type對象。

前面一篇文章我們講到了什麼是數組标量類型。數組标量類型是可以通過np.type來通路的資料類型。 比如:

np.int32

,

np.complex128

等。

我們看下數組标量的轉換:

In [85]: np.dtype(np.int32)
Out[85]: dtype('int32')
In [86]: np.dtype(np.complex128)
Out[86]: dtype('complex128')      

這些以np開頭的内置數組标量類型可以參考我之前寫的文章 “NumPy之:資料類型” 。

注意,數組标量并不是dtype對象,雖然很多情況下,可以在需要使用dtype對象的時候都可以使用數組标量。

通用類型

一些通用類型對象,可以被轉換成為相應的dtype類型:

通用類型對象 dtype類型

number

inexact

floating

float

complexfloating

cfloat

integer

signedinteger

int_

unsignedinteger

uint

character

string

generic

flexible

void

内置Python類型

一些Python内置的類型和數組标量類型是等價的,也可以被轉換成為dtype:

Python類型
int

int_

bool

bool_

float_

complex

cfloat

bytes

bytes_

str

str_

buffer

void

(all others)

object_

看下内置Python類型轉換的例子:

In [82]: np.dtype(float)
Out[82]: dtype('float64')
In [83]: np.dtype(int)
Out[83]: dtype('int64')
In [84]:  np.dtype(object)
Out[84]: dtype('O')      

帶有.dtype屬性的對象

任何type對象隻要包含

dtype

屬性,并且這個屬性屬于可以轉換的範圍的話,都可以被轉換成為dtype。

一個字元的string對象

對于每個内置的資料類型來說都有一個和它對應的字元編碼,我們也可以使用這些字元編碼來進行轉換:

In [134]: np.dtype('b')  # byte, native byte order
Out[134]: dtype('int8')
In [135]: np.dtype('>H')  # big-endian unsigned short
Out[135]: dtype('>u2')
In [136]: np.dtype('<f') # little-endian single-precision float
Out[136]: dtype('float32')
In [137]: np.dtype('d') # double-precision floating-point number
Out[137]: dtype('float64')      

數組類型的String

Numpy中數組類型的對象有一個屬性叫做typestr。

typestr描述了這個數組中存放的資料類型和長度。

typestr由三部分組成,第一部分是描述資料位元組順序:

<

小端

>

大端。

第二部分是數組裡面元素的基本類型:

類型 描述

t

Bit field (following integer gives the number of bits in the bit field).

b

Boolean (integer type where all values are only True or False)

i

Integer

u

Unsigned integer

f

Floating point

c

Complex floating point

m

Timedelta

M

Datetime

O

Object (i.e. the memory contains a pointer to PyObject)

S

String (fixed-length sequence of char)

U

Unicode (fixed-length sequence of Py_UNICODE)

V

Other (void * – each item is a fixed-size chunk of memory)

最後一部分就是資料的長度。

dtype支援下面幾種類型的轉換:

'?'

boolean

'b'

(signed) byte

'B'

unsigned byte

'i'

(signed) integer

'u'

unsigned integer

'f'

floating-point

'c'

complex-floating point

'm'

timedelta

'M'

datetime

'O'

(Python) objects

'S'

'a'

zero-terminated bytes (not recommended)

'U'

Unicode string

'V'

raw data (

void

)

我們看幾個例子:

In [137]: np.dtype('d')
Out[137]: dtype('float64')
In [138]: np.dtype('i4')
Out[138]: dtype('int32')
In [139]: np.dtype('f8')
Out[139]: dtype('float64')
In [140]:  np.dtype('c16')
Out[140]: dtype('complex128')
In [141]: np.dtype('a25')
Out[141]: dtype('S25')
In [142]: np.dtype('U25')
Out[142]: dtype('<U25')      

逗号分割的字元串

逗号分割的字元串可以用來表示結構化的資料類型。

對于這種結構化的資料類型也可以轉換成為dtpye格式,轉換後的dtype,将會以f1,f2, … fn-1作為名字來儲存對應的格式資料。我們舉個例子:

In [143]: np.dtype("i4, (2,3)f8, f4")
Out[143]: dtype([('f0', '<i4'), ('f1', '<f8', (2, 3)), ('f2', '<f4')])      

上面的例子中,f0儲存的是32位的整數,f1儲存的是 2 x 3 數組的64-bit 浮點數。f2是一個32-bit 的浮點數。

再看另外一個例子:

In [144]: np.dtype("a3, 3u8, (3,4)a10")
Out[144]: dtype([('f0', 'S3'), ('f1', '<u8', (3,)), ('f2', 'S10', (3, 4))])      

類型字元串

所有在

numpy.sctypeDict

.keys()中的字元,都可以被轉換為dtype:

In [146]: np.sctypeDict.keys()
Out[146]: dict_keys(['?', 0, 'byte', 'b', 1, 'ubyte', 'B', 2, 'short', 'h', 3, 'ushort', 'H', 4, 'i', 5, 'uint', 'I', 6, 'intp', 'p', 7, 'uintp', 'P', 8, 'long', 'l', 'L', 'longlong', 'q', 9, 'ulonglong', 'Q', 10, 'half', 'e', 23, 'f', 11, 'double', 'd', 12, 'longdouble', 'g', 13, 'cfloat', 'F', 14, 'cdouble', 'D', 15, 'clongdouble', 'G', 16, 'O', 17, 'S', 18, 'unicode', 'U', 19, 'void', 'V', 20, 'M', 21, 'm', 22, 'bool8', 'Bool', 'b1', 'float16', 'Float16', 'f2', 'float32', 'Float32', 'f4', 'float64', 'Float64', 'f8', 'float128', 'Float128', 'f16', 'complex64', 'Complex32', 'c8', 'complex128', 'Complex64', 'c16', 'complex256', 'Complex128', 'c32', 'object0', 'Object0', 'bytes0', 'Bytes0', 'str0', 'Str0', 'void0', 'Void0', 'datetime64', 'Datetime64', 'M8', 'timedelta64', 'Timedelta64', 'm8', 'int64', 'uint64', 'Int64', 'UInt64', 'i8', 'u8', 'int32', 'uint32', 'Int32', 'UInt32', 'i4', 'u4', 'int16', 'uint16', 'Int16', 'UInt16', 'i2', 'u2', 'int8', 'uint8', 'Int8', 'UInt8', 'i1', 'u1', 'complex_', 'int0', 'uint0', 'single', 'csingle', 'singlecomplex', 'float_', 'intc', 'uintc', 'int_', 'longfloat', 'clongfloat', 'longcomplex', 'bool_', 'unicode_', 'object_', 'bytes_', 'str_', 'string_', 'int', 'float', 'complex', 'bool', 'object', 'str', 'bytes', 'a'])      

使用的例子:

In [147]: np.dtype('uint32')
Out[147]: dtype('uint32')
In [148]: np.dtype('float64')
Out[148]: dtype('float64')      

元組

通過使用dtype構成的元組,我們可以生成新的dtype。

元組也有很多種方式。

(flexible_dtype, itemsize)

對于不固定長度的dtype,可以指定size:

In [149]: np.dtype((np.void, 10))
Out[149]: dtype('V10')
In [150]: np.dtype(('U', 10))
Out[150]: dtype('<U10')      

(fixed_dtype, shape)

對于固定長度的dtype,可以指定shape:

In [151]:  np.dtype((np.int32, (2,2)))
Out[151]: dtype(('<i4', (2, 2)))
In [152]: np.dtype(('i4, (2,3)f8, f4', (2,3)))
Out[152]: dtype(([('f0', '<i4'), ('f1', '<f8', (2, 3)), ('f2', '<f4')], (2, 3)))      

[(field_name, field_dtype, field_shape), …]

list中的元素是一個個的field,每個field都是由2-3個部分組成的,分别是field名字,field類型,field的shape。

field_name如果是 ’ ‘的話,就會使用預設的f1,f2 ….作為名字。field_name 也可以是一個2元組,由title 和 name 組成。

field_dtype 就是field的dtype類型。

shape是一個可選字段,如果field_dtype是一個數組的話,就需要指定shape。

In [153]: np.dtype([('big', '>i4'), ('little', '<i4')])
Out[153]: dtype([('big', '>i4'), ('little', '<i4')])      

上面是兩個字段,一個是大端的32位的int,一個是小端的32位的int。

In [154]: np.dtype([('R','u1'), ('G','u1'), ('B','u1'), ('A','u1')])
Out[154]: dtype([('R', 'u1'), ('G', 'u1'), ('B', 'u1'), ('A', 'u1')])      

四個字段,每個都是無符号整形。

{‘names’: …, ‘formats’: …, ‘offsets’: …, ‘titles’: …, ‘itemsize’: …}

這種寫法可以指定name清單和formats清單:

In [157]: np.dtype({'names': ['r','g','b','a'], 'formats': [np.uint8, np.uint8, np.uint8, np.uint8]})
Out[157]: dtype([('r', 'u1'), ('g', 'u1'), ('b', 'u1'), ('a', 'u1')])      

offsets 指的是每個字段的byte offsets。titles 是字段的title,itemsize 是整個dtype的size。

In [158]: np.dtype({'names': ['r','b'], 'formats': ['u1', 'u1'],
     ...:                'offsets': [0, 2],
     ...:                'titles': ['Red pixel', 'Blue pixel']})
     ...:
Out[158]: dtype({'names':['r','b'], 'formats':['u1','u1'], 'offsets':[0,2], 'titles':['Red pixel','Blue pixel'], 'itemsize':3})      

(base_dtype, new_dtype)

可以将基本的dtype類型轉換為結構化的dtype類型:

In [159]: np.dtype((np.int32,{'real':(np.int16, 0),'imag':(np.int16, 2)}))
Out[159]: dtype([('real', '<i2'), ('imag', '<i2')])      

32位的int轉換成兩個16位的int。

In [161]: np.dtype(('i4', [('r','u1'),('g','u1'),('b','u1'),('a','u1')]))
Out[161]: dtype([('r', 'u1'), ('g', 'u1'), ('b', 'u1'), ('a', 'u1')])      

32位的int,轉換成4個unsigned integers。

本文已收錄于 http://www.flydean.com/04-python-numpy-datatype-obj/

最通俗的解讀,最深刻的幹貨,最簡潔的教程,衆多你不知道的小技巧等你來發現!

歡迎關注我的公衆号:「程式那些事」,懂技術,更懂你!