大家好,歡迎來到數據新手村的第十一天!昨天我們學會了各種「無中生有」的陣列創建方法,但可能已經注意到,在創建陣列時,常常伴隨著一個神秘的參數:dtype
。
# 像這樣...
arr = np.zeros((2, 3), dtype=int)
ndarray 的同質性(所有元素類型必須一致)是它高效能的基石,而 dtype 正是定義這個「共同類型」的關鍵。今天就要來深入探討這個決定陣列靈魂的 dtype 屬性。
類型 (Type): 整數 (int)、浮點數 (float)、布林 (bool) 等。
大小 (Size): 該類型佔用多少記憶體空間(例如 8-bit, 16-bit, 32-bit, 64-bit)。
字節序 (Byte Order): 處理器讀取多字節數據的順序(這屬於進階概念,我們先不深入)。
選擇正確的 dtype,對於節省記憶體空間、提升運算速度、以及確保數值計算的精確度都至關重要。
bool
| True
或 False
值 | N/A |int8
| 8 位元有號整數 | -128
~ 127
|int16
| 16 位元有號整數 | -32,768
~ 32,767
|int32
| 32 位元有號整數 | 約 -21億
~ 21億
|int64
| 64 位元有號整數 | 一個非常大的範圍 |uint8
| 8 位元無號整數 | 0
~ 255
|uint16
| 16 位元無號整數 | 0
~ 65,535
|float16
| 半精度浮點數 | N/A (表示小數) |float32
| 單精度浮點數 | N/A (表示小數) |float64
| 雙精度浮點數 | N/A (表示小數) |complex64
| 由兩個 32 位元浮點數表示 | N/A (表示複數) |complex128
| 由兩個 64 位元浮點數表示 | N/A (表示複數) |int8 vs. uint8 深度解析
為什麼 int8 的範圍是 -128 ~ 127,而 uint8 卻是 0 ~ 255?
這背後的原理是「符號位元」。一個 8-bit 的空間,總共可以表示 2 ^ 8 =256 種狀態。
對於 int8 (有號),電腦會犧牲 1 個 bit 來表示正負號,剩下 7 個 bits 來表示數值,所以範圍是 -128 到 127。
對於 uint8 (無號),全部 8 個 bits 都用來表示數值,所以範圍是 0 到 255。
類型 | 位元數 | 符號 | 範圍 |
---|---|---|---|
int8 |
8 | 有 | -128 ~ 127 |
uint8 |
8 | 無 | 0 ~ 255 |
import numpy as np
arr = np.array([1, 0, 2, 0], dtype='bool')
print(arr)
arr = np.array([1, 0, 2, 0], dtype=np.bool)
print(arr)
輸出結果:
[ True False True False]
[ True False True False]
arr = np.array([1, 0, 2, 0], dtype=np.int8)
print(arr)
arr = np.array([1, 0, 2, 0], dtype=int)
print(arr)
# Error:超過範圍
# arr = np.array([1, 0, 2000, 0], dtype=np.int8)
# print(arr)
輸出結果:
[1 0 2 0]
[1 0 2 0]
# 建立一個由 32 位元浮點數組成的陣列
arr_float32 = np.array([1, 2, 3], dtype=np.float32)
print(f"陣列: {arr_float32}")
print(f"資料類型: {arr_float32.dtype}")
print(f"每個元素佔用字節: {arr_float32.itemsize}") # float32 = 4 bytes (32/8)
輸出結果:
陣列: [1. 2. 3.]
資料類型: float32
每個元素佔用字節: 4
使用 .astype() 轉換現有陣列的 dtype (非常重要!)
astype() 是我們未來進行資料清理時,一定會用到的函式。它可以將一個現有陣列的資料類型,轉換成我們指定的另一種新類型,並回傳一個新的陣列。
arr_int = np.array([0, 1, 2, 3, 4])
print(f"原始整數陣列: {arr_int}, dtype: {arr_int.dtype}")
# 將整數陣列轉換為浮點數陣列
arr_float = arr_int.astype(np.float64)
print(f"轉換後的浮點數陣列: {arr_float}, dtype: {arr_float.dtype}")
# 將浮點數陣列轉換為布林陣列 (0 會變成 False, 其他數字變成 True)
arr_bool = arr_float.astype(np.bool_)
print(f"轉換後的布林陣列: {arr_bool}, dtype: {arr_bool.dtype}")
輸出結果:
原始整數陣列: [0 1 2 3 4], dtype: int64
轉換後的浮點數陣列: [0. 1. 2. 3. 4.], dtype: float64
轉換後的布林陣列: [False True True True True], dtype: bool
結語
今天我們深入了解了 NumPy 陣列的靈魂——資料類型 dtype。理解 dtype 不僅能讓我們更有效地管理記憶體,更是進行精確數值計算和資料清洗的基礎。尤其是 .astype() 這個方法,請務必牢記,它在未來 Pandas 的學習中會頻繁出現。
既然我們已經能掌控陣列的內部資料類型,明天 Day 12,我們將學習如何精準地操作陣列的「肉體」——也就是存取、選取、過濾其中的每一個元素。 我們將正式進入索引與切片的世界!