大家好,歡迎來到數據新手村的第十二天!昨天深入了解了陣列的靈魂——資料類型 dtype
。今天要學習如何精準地操作陣列的「肉體」——也就是存取 (Access)、選取 (Select)、過濾 (Filter) 其中的每一個元素。這就是索引 (Indexing) 與切片 (Slicing) 的威力,是我們與數據互動最基本、也最重要的技能。
一維陣列的操作和 Python 的 list 非常相似,是熱身的最好起點。
索引從 0
開始,也可以使用負數從尾端倒著數,arr[-1]
代表最後一個元素。
import numpy as np
arr = np.random.randint(1, 100, 20)
print(arr)
輸出結果:
[17 63 17 8 99 7 27 14 76 59 26 4 75 76 62 78 84 58 95 33]
切片 (Slicing)
切片的語法是 [start:stop:step],並且遵循「左閉右開」原則,也就是包含 start 但不包含 stop。
print(arr[10]) #基礎索引
print(arr[:]) # 獲取全部的數據
# 取出索引 2 到索引 5 (不含) 的元素
print(arr[2:5]) # start:end+1
print(arr[slice(2, 15, 3)]) # # start, end+1, step
# 從頭取到索引 5 (不含)
print(f"前 5 個元素: {arr[:5]}")
# 從索引 5 取到結尾
print(f"索引 5 之後的所有元素: {arr[5:]}")
# 每隔一個元素取樣
print(f"偶數索引的元素: {arr[::2]}")
print(arr[(arr > 10) & (arr < 70)]) # 布林索引
輸出結果:
11
[15 5 28 76 9 7 27 80 83 79 11 34 86 18 41 83 43 61 85 31]
[28 76 9]
[28 7 83 34 41]
前 5 個元素: [15 5 28 76 9]
索引 5 之後的所有元素: [ 7 27 80 83 79 11 34 86 18 41 83 43 61 85 31]
偶數索引的元素: [15 28 9 27 83 11 86 41 43 85]
[15 28 27 11 34 18 41 43 61 31]
對於二維陣列(矩陣),NumPy 提供了更強大、更高效的索引方式。
最佳實踐:arr[row, col]
要存取二維陣列中的單一元素,最標準、最高效的寫法是 arr[row, col]。這就像給圖書館員一個 (橫排, 直排) 的完整座標,一次就定位。應盡量避免使用 arr[row][col] 這種效率較低的鏈式寫法。
# 二維陣列的索引與切片
arr = np.random.randint(1, 100, (4, 8))
print(arr)
輸出結果:
[[11 7 76 19 4 78 18 44]
[17 19 80 91 60 72 76 30]
[46 7 64 79 25 19 94 34]
[79 43 95 4 19 71 53 23]]
切片應用
我們可以將切片語法應用在行和列上,來取出子陣列。
print(arr[1, 3]) # 直接訪問/元組式訪問 --> 單一、高效的動作
print(arr[1][3]) # 鏈式訪問/項目式訪問 --> 兩步驟的過程
print(arr[:, :]) # 獲取全部的數據
print(arr[1, 2:5])
print(arr[:, 3]) #針對列數據
# 取出右上角的 2x2 子矩陣
sub_matrix = arr_2d[0:2, 1:3]
print(f"\n右上角的 2x2 子矩陣:\n{sub_matrix}")
輸出結果:
[[37 9 49 20 49 96 54 11]
[39 10 61 61 24 53 97 77]
[79 96 55 82 74 28 40 88]
[10 15 32 57 57 59 80 28]]
[61 61 24]
[20 61 82 57]
右上角的 2x2 子矩陣:
[[2 3]
[5 6]]
這是 NumPy 最強大、在數據分析中最常用的索引方式。它讓我們可以基於「條件」來篩選資料。它的運作分為兩步驟:
建立一個布林條件 (例如 arr > 25),這會產生一個由 True/False 組成的「篩網」陣列。
再將這個「篩網」陣列放回 [] 中,就能篩選出所有 True 位置對應的原始元素。
print(arr[arr > 50]) # 布林索引 --> 會返回一維陣列
print(arr[2][arr[2] > 50])
print(arr[2]>50) # 補充:「先索引第 2 行,再對該行所有元素做 > 50 的判斷,最終返回一個布林陣列」
輸出結果:
[96 54 61 61 53 97 77 79 96 55 82 74 88 57 57 59 80]
[79 96 55 82 74 88]
[ True True True True True False False True]
結語
今天掌握了從 NumPy 陣列中取出資料的各種神技,尤其是「布林索引」,它將是未來進行數據篩選與清洗時最重要的工具。
掌握了創建、檢視、與選取陣列的技巧後,終於要來釋放 NumPy 的真正力量了。明天,Day 13,我們將徹底告別 for 迴圈,學習 NumPy 的靈魂——向量化運算!