數組類型之間的轉換
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/