Python 中 NumPy 的數據類型

數組類型之間的轉換

NumPy 中有些數據類型是與 C 中的數據類型是類似的。

Numpy 的類型 C 的類型 描述
np.bool bool 存儲爲字節的布爾值(True或False)
np.byte signed char 平臺定義
np.ubyte unsigned char 平臺定義
np.short short 平臺定義
np.ushort unsigned short 平臺定義
np.intc int 平臺定義
np.uintc unsigned int 平臺定義
np.int_ long 平臺定義
np.uint unsigned long 平臺定義
np.longlong long long 平臺定義
np.ulonglong unsigned long long 平臺定義
np.half / np.float16   半精度浮點數:符號位,5位指數,10位尾數
np.single float 平臺定義的單精度浮點數:通常爲符號位,8位指數,23位尾數
np.double double 平臺定義的雙精度浮點數:通常爲符號位,11位指數,52位尾數。
np.longdouble long double 平臺定義的擴展精度浮點數
np.csingle float complex 複數,由兩個單精度浮點數(實部和虛部)表示
np.cdouble double complex 複數,由兩個雙精度浮點數(實部和虛部)表示。
np.clongdouble long double complex 複數,由兩個擴展精度浮點數(實部和虛部)表示。

其中依賴平臺本身定義的數據類型有一組固定大小的別名:

Numpy 的類型 C 的類型 描述
np.int8 int8_t 字節(-128到127)
np.int16 int16_t 整數(-32768至32767)
np.int32 int32_t 整數(-2147483648至2147483647)
np.int64 int64_t 整數(-9223372036854775808至9223372036854775807)
np.uint8 uint8_t 無符號整數(0到255)
np.uint16 uint16_t 無符號整數(0到65535)
np.uint32 uint32_t 無符號整數(0到4294967295)
np.uint64 uint64_t 無符號整數(0到18446744073709551615)
np.intp intptr_t 用於索引的整數,通常與索引相同 ssize_t
np.uintp uintptr_t 整數大到足以容納指針
np.float32 float  
np.float64 / np.float_ double 與內置 python float 的精度相匹配。
np.complex64 float complex 複數,由兩個32位浮點數(實數和虛數組件)表示
np.complex128 / np.complex_ double complex 與內置python 複合體的精度相匹配。

NumPy 數值類型是 dtype(數據類型)對象的實例,每個對象都具有獨特的特徵。使用下述語句導入 NumPy

>>> import numpy as np

在 dtypes 可作爲 np.bool_,np.float32 等等。

有 5 種基本數字類型表示布爾值(bool),整數(int),無符號整數(uint)浮點(浮點數)和複數。名稱中帶有數字的那些表示該類型的位大小(即,在內存中表示單個值需要多少位)。某些類型(例如 int 和 intp)具有不同的位,取決於平臺(例如,32位與64位計算機)。

數據類型可以用作將 python 數據轉換爲數組標量的函數,將 python 數字序列轉換爲該類型的數組,或作爲許多 numpy 函數或方法接受的 dtype 關鍵字的參數。如:

>>> import numpy as np
>>> x = np.float32(1.0)
>>> x
1.0
>>> y = np.int_([1,2,4])
>>> y
array([1, 2, 4])
>>> z = np.arange(3, dtype=np.uint8)
>>> z
array([0, 1, 2], dtype=uint8)

數組類型也可以通過字符代碼引用,主要是爲了保持與較舊的包(如 Numeric)的向後兼容性(並不建議)。有些文檔可能仍然引用這些,例如:

>>> np.array([1, 2, 3], dtype='f')
array([ 1.,  2.,  3.], dtype=float32)

要轉換數組的類型,請使用 .astype() 方法(建議)或類型本身作爲函數。例如:

>>> z.astype(float)                 
array([  0.,  1.,  2.])
>>> np.int8(z)
array([0, 1, 2], dtype=int8)

注意,在上面,我們使用 Python 的 float 對象作爲 dtype。NumPy 中 int 是指 np.int_,bool 意味着 np.bool_,這 float 是 np.float_和 complex 是 np.complex_。其他數據類型沒有類似的 Python 等價物。

要確定數組的類型,可以查看 dtype 屬性:

>>> z.dtype
dtype('uint8')

dtype 對象還包含有關類型的信息,例如其位寬和字節順序。數據類型也可以間接用於查詢類型的屬性,例如它是否爲整數:

>>> d = np.dtype(int)
>>> d
dtype('int32')

>>> np.issubdtype(d, np.integer)
True

>>> np.issubdtype(d, np.floating)
False

數組標量

NumPy 通常將數組元素作爲數組標量返回(帶有關聯 dtype 的標量)。數組標量與 Python 標量不同,但在大多數情況下它們可以互換使用。有一些例外,例如當代碼需要標量的非常特定的屬性或者它特定地檢查值是否是 Python 標量時。通常,存在的問題很容易被顯式轉換數組標量到 Python 標量,採用相應的 Python 類型的功能(例如,固定的 int,float,complex,str,unicode)。

使用數組標量的主要優點是它們保留了數組類型(Python 可能沒有匹配的標量類型,例如 int16)。因此,使用數組標量可確保數組和標量之間的相同行爲,無論值是否在數組內。NumPy 標量也有許多與數組相同的方法。

建議在較多使用 ndarray 對象的地方,使用統一的數據類型,避免數據之間繁瑣顯式轉換。

溢出錯誤

當值需要比數據類型中的可用內存更多的內存時,NumPy 數值類型的固定大小可能會導致溢出錯誤。如:

>>> np.power(100, 8, dtype=np.int64)
10000000000000000
>>> np.power(100, 8, dtype=np.int32)
1874919424

NumPy 和 Python 整數類型的行爲在整數溢出方面存在顯着差異。與 NumPy 不同,Python 的大小 int 是靈活的。這意味着 Python 整數可以擴展以容納任何整數並且不會溢出。

NumPy 分別提供 numpy.iinfo 和 numpy.finfo 驗證 NumPy 整數和浮點值的最小值或最大值:

>>> np.iinfo(np.int) # Bounds of the default integer on this system.
iinfo(min=-9223372036854775808, max=9223372036854775807, dtype=int64)
>>> np.iinfo(np.int32) # Bounds of a 32-bit integer
iinfo(min=-2147483648, max=2147483647, dtype=int32)
>>> np.iinfo(np.int64) # Bounds of a 64-bit integer
iinfo(min=-9223372036854775808, max=9223372036854775807, dtype=int64)

如果 64 位整數仍然太小,則結果可能會轉換爲浮點數。浮點數提供了更大但不精確的可能值範圍。

>>> np.power(100, 100, dtype=np.int64) # Incorrect even with 64-bit int
0
>>> np.power(100, 100, dtype=np.float64)
1e+200

擴展精度

Python 的浮點數通常是 64 位浮點數,幾乎等同於 np.float64。但某些情況下,使用更精確的浮點數可能會很有用。這在 numpy 中是否可行取決於硬件和開發環境:具體地說,x86 機器提供 80 位精度的硬件浮點,雖然大多數 C 編譯器提供這一點作爲它們的 long double 類型,MSVC(Windows 構建的標準)使 long double 等同於 double (64位)。NumPy 使編譯器的 long double 作爲 np.longdouble 可用(而 np.clongdouble 用於複數)。

NumPy 不提供比 C 的 long double 更高精度的 dtype;特別是 128 位 IEEE 四精度數據類型不可用。

參考資料:

1. NumPy 官方文檔:https://numpy.org/devdocs/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章