數(shù)據(jù)類型

數(shù)組類型之間的轉(zhuǎn)換

NumPy支持比Python更多種類的數(shù)字類型。本節(jié)顯示了哪些可用,以及如何修改數(shù)組的數(shù)據(jù)類型。

支持的原始類型與 C 中的原始類型緊密相關:

Numpy 的類型 C 的類型 描述
np.bool bool 存儲為字節(jié)的布爾值(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
半精度浮點數(shù):符號位,5位指數(shù),10位尾數(shù)
np.single float 平臺定義的單精度浮點數(shù):通常為符號位,8位指數(shù),23位尾數(shù)
np.double double 平臺定義的雙精度浮點數(shù):通常為符號位,11位指數(shù),52位尾數(shù)。
np.longdouble long double 平臺定義的擴展精度浮點數(shù)
np.csingle float complex 復數(shù),由兩個單精度浮點數(shù)(實部和虛部)表示
np.cdouble double complex 復數(shù),由兩個雙精度浮點數(shù)(實部和虛部)表示。
np.clongdouble long double complex 復數(shù),由兩個擴展精度浮點數(shù)(實部和虛部)表示。

由于其中許多都具有依賴于平臺的定義,因此提供了一組固定大小的別名:

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

NumPy數(shù)值類型是dtype(數(shù)據(jù)類型)對象的實例,每個對象都具有獨特的特征。使用后導入NumPy

>>> import numpy as np

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

上表中未列出的高級類型將在結構化數(shù)組中進行探討。

有5種基本數(shù)字類型表示布爾值(bool),整數(shù)(int),無符號整數(shù)(uint)浮點(浮點數(shù))和復數(shù)。名稱中帶有數(shù)字的那些表示該類型的位大?。?,在內(nèi)存中表示單個值需要多少位)。某些類型(例如 intintp)具有不同的位,取決于平臺(例如,32位與64位計算機)。在與尋址原始內(nèi)存的低級代碼(例如C或Fortran)連接時,應考慮這一點。

數(shù)據(jù)類型可以用作將python數(shù)轉(zhuǎn)換為數(shù)組標量的函數(shù)(請參閱數(shù)組標量部分以獲得解釋),將python數(shù)字序列轉(zhuǎn)換為該類型的數(shù)組,或作為許多numpy函數(shù)或方法接受的dtype關鍵字的參數(shù)。一些例子:

>>> 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)

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

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

我們建議使用dtype對象。

要轉(zhuǎn)換數(shù)組的類型,請使用 .astype() 方法(首選)或類型本身作為函數(shù)。例如:

>>> 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_,這floatnp.float_complexnp.complex_。其他數(shù)據(jù)類型沒有Python等價物。

要確定數(shù)組的類型,請查看dtype屬性:

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

dtype對象還包含有關類型的信息,例如其位寬和字節(jié)順序。數(shù)據(jù)類型也可以間接用于查詢類型的屬性,例如它是否為整數(shù):

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

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

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

數(shù)組標量

NumPy通常將數(shù)組元素作為數(shù)組標量返回(帶有關聯(lián)dtype的標量)。數(shù)組標量與Python標量不同,但在大多數(shù)情況下它們可以互換使用(主要的例外是早于v2.x的Python版本,其中整數(shù)數(shù)組標量不能作為列表和元組的索引)。有一些例外,例如當代碼需要標量的非常特定的屬性或者它特定地檢查值是否是Python標量時。通常,存在的問題很容易被顯式轉(zhuǎn)換數(shù)組標量到Python標量,采用相應的Python類型的功能(例如,固定的int,float,complex,str,unicode)。

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

溢出錯誤

當值需要比數(shù)據(jù)類型中的可用內(nèi)存更多的內(nèi)存時,NumPy數(shù)值類型的固定大小可能會導致溢出錯誤。例如,numpy.power對于64位整數(shù)正確計算 100 * 10 * 8,但對于32位整數(shù)給出1874919424(不正確)。

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

NumPy和Python整數(shù)類型的行為在整數(shù)溢出方面存在顯著差異,并且可能會使用戶期望NumPy整數(shù)的行為類似于Python int。與 NumPy 不同,Python 的大小int 是靈活的。這意味著Python整數(shù)可以擴展以容納任何整數(shù)并且不會溢出。

NumPy分別提供numpy.iinfo

numpy.finfo

驗證NumPy整數(shù)和浮點值的最小值或最大值:

>>> 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位整數(shù)仍然太小,則結果可能會轉(zhuǎn)換為浮點數(shù)。浮點數(shù)提供了更大但不精確的可能值范圍。

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

擴展精度

Python 的浮點數(shù)通常是64位浮點數(shù),幾乎等同于 np.float64 。在某些不尋常的情況下,使用更精確的浮點數(shù)可能會很有用。這在numpy中是否可行取決于硬件和開發(fā)環(huán)境:具體地說,x86機器提供80位精度的硬件浮點,雖然大多數(shù)C編譯器提供這一點作為它們的 long double 類型,MSVC(Windows構建的標準)使 long double 等同于 double (64位)。NumPy使編譯器的 long double 作為 np.longdouble 可用(而 np.clongdouble 用于復數(shù))。您可以使用 np.finfo(np.longdouble) 找出 numpy提供了什么。

NumPy不提供比C的 long double 更高精度的dtype;特別是128位IEEE四精度數(shù)據(jù)類型(FORTRAN的 REAL*16 )不可用。

為了有效地進行內(nèi)存的校準,np.longdouble通常以零位進行填充,即96或者128位, 哪個更有效率取決于硬件和開發(fā)環(huán)境;通常在32位系統(tǒng)上它們被填充到96位,而在64位系統(tǒng)上它們通常被填充到128位。np.longdouble被填充到系統(tǒng)默認值;為需要特定填充的用戶提供了np.float96np.float128。盡管它們的名稱是這樣叫的, 但是np.float96np.float128只提供與np.longdouble一樣的精度, 即大多數(shù)x86機器上的80位和標準Windows版本中的64位。

請注意,即使np.longdouble提供比python float更多的精度,也很容易失去額外的精度,因為python通常強制值通過float傳遞值。例如,%格式操作符要求將其參數(shù)轉(zhuǎn)換為標準python類型,因此即使請求了許多小數(shù)位,也不可能保留擴展精度。使用值1 + np.finfo(np.longdouble).eps測試你的代碼非常有用。

作者:柯廣的網(wǎng)絡日志 ? 數(shù)據(jù)類型


微信公眾號:Java大數(shù)據(jù)與數(shù)據(jù)倉庫