iT邦幫忙

2025 iThome 鐵人賽

DAY 11
0
自我挑戰組

數據新手村:統計系畢業生 30 天打怪升級之旅系列 第 11

Day 11 - 深入 NumPy 的資料類型 (dtype)

  • 分享至 

  • xImage
  •  

大家好,歡迎來到數據新手村的第十一天!昨天我們學會了各種「無中生有」的陣列創建方法,但可能已經注意到,在創建陣列時,常常伴隨著一個神秘的參數:dtype

# 像這樣...
arr = np.zeros((2, 3), dtype=int)

ndarray 的同質性(所有元素類型必須一致)是它高效能的基石,而 dtype 正是定義這個「共同類型」的關鍵。今天就要來深入探討這個決定陣列靈魂的 dtype 屬性。

  1. 什麼是 dtype?
    dtype (data type) 是 NumPy 中一個特殊的物件,它描述了 ndarray 中每個元素的具體類型。它不僅僅告訴我們這是「整數」還是「浮點數」,還包含了更精細的資訊,例如:
  • 類型 (Type): 整數 (int)、浮點數 (float)、布林 (bool) 等。

  • 大小 (Size): 該類型佔用多少記憶體空間(例如 8-bit, 16-bit, 32-bit, 64-bit)。

  • 字節序 (Byte Order): 處理器讀取多字節數據的順序(這屬於進階概念,我們先不深入)。

選擇正確的 dtype,對於節省記憶體空間、提升運算速度、以及確保數值計算的精確度都至關重要。

  1. NumPy 的常見資料類型
    | 類型大類 | 具體 dtype | 說明 | 範圍 (Range) |
    | :--- | :--- | :--- | :--- |
    | 布林 (Boolean) | bool | TrueFalse 值 | N/A |
    | 有號整數 (Integer) | int8 | 8 位元有號整數 | -128 ~ 127 |
    | | int16 | 16 位元有號整數 | -32,768 ~ 32,767 |
    | | int32 | 32 位元有號整數 | 約 -21億 ~ 21億 |
    | | int64 | 64 位元有號整數 | 一個非常大的範圍 |
    | 無號整數 (Unsigned Int) | uint8 | 8 位元無號整數 | 0 ~ 255 |
    | | uint16 | 16 位元無號整數 | 0 ~ 65,535 |
    | 浮點數 (Float) | float16 | 半精度浮點數 | N/A (表示小數) |
    | | float32 | 單精度浮點數 | N/A (表示小數) |
    | | float64 | 雙精度浮點數 | N/A (表示小數) |
    | 複數 (Complex) | 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
  1. 如何指定與轉換 dtype
    在創建時指定 dtype
    我們可以在創建陣列時,明確地告訴 NumPy 我們想要的資料類型。
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,我們將學習如何精準地操作陣列的「肉體」——也就是存取、選取、過濾其中的每一個元素。 我們將正式進入索引與切片的世界!


上一篇
Day 10 - 精通 NumPy 陣列的創建方法
下一篇
Day 12 - NumPy 陣列的索引與切片神技
系列文
數據新手村:統計系畢業生 30 天打怪升級之旅12
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言