人工智能之數據分析 numpy
第五章 索引與切片
(文章目錄)
前言
在 NumPy 中,索引(indexing)與切片(slicing) 是訪問和操作 ndarray 元素的核心手段。相比 Python 原生列表,NumPy 提供了更強大、更靈活的多維索引機制,包括基本索引、高級索引、布爾索引、花式索引等。
本文詳細講解 NumPy 數組的索引與切片方法。
一、基本索引與切片(Basic Indexing and Slicing)
適用於整數、切片對象(:),返回的是原數組的視圖(view)(不復制數據)。
1. 一維數組
import numpy as np
a = np.array([10, 20, 30, 40, 50])
# 索引(從0開始)
print(a[0]) # 10
print(a[-1]) # 50(倒數第一個)
# 切片:start:stop:step
print(a[1:4]) # [20 30 40](不包含索引4)
print(a[:3]) # [10 20 30]
print(a[::2]) # [10 30 50](步長為2)
print(a[::-1]) # [50 40 30 20 10](反轉)
✅ 切片返回的是視圖,修改會影響原數組:
b = a[1:3]
b[0] = 999
print(a) # [10 999 30 40 50] ← 原數組被修改!
2. 多維數組(以二維為例)
arr = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
(1) 單個元素訪問
print(arr[0, 1]) # 等價於 arr[0][1] → 2
print(arr[-1, -1]) # 9
推薦使用
arr[i, j]而非arr[i][j],前者更高效且支持高級功能。
(2) 行/列切片
print(arr[1, :]) # 第1行所有列 → [4 5 6]
print(arr[:, 2]) # 第2列所有行 → [3 6 9]
print(arr[0:2, 1:3]) # 前兩行,第1~2列
# [[2 3]
# [5 6]]
(3) 使用省略號 ...
適用於高維數組,自動補全冒號:
# 三維數組
x = np.random.rand(2, 3, 4)
print(x[..., 0]) # 等價於 x[:, :, 0] → 取最後一維第0個
二、高級索引(Advanced Indexing)
當使用整數數組、布爾數組進行索引時,觸發高級索引,返回副本(copy),而非視圖。
1. 整數數組索引(花式索引,Fancy Indexing)
用整數列表或數組指定要取的索引位置。
arr = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
# 取第0行和第2行
print(arr[[0, 2]])
# [[1 2 3]
# [7 8 9]]
# 同時指定行和列(一一對應)
print(arr[[0, 1, 2], [0, 1, 2]]) # → [1, 5, 9](對角線)
# 等價於 [arr[0,0], arr[1,1], arr[2,2]]
# 取任意位置組合
rows = np.array([0, 2])
cols = np.array([2, 0])
print(arr[rows, cols]) # [3, 7]
⚠️ 注意:
arr[[0,1],[0,1]]≠arr[0:2, 0:2]前者是高級索引(取兩個點),後者是基本切片(取子矩陣)。
2. 布爾索引(Boolean Indexing)
用布爾數組篩選滿足條件的元素。
arr = np.array([10, 20, 30, 40, 50])
# 創建布爾掩碼
mask = arr > 30
print(mask) # [False False False True True]
print(arr[mask]) # [40 50]
# 直接在索引中寫條件
print(arr[arr % 20 == 0]) # [20 40]
# 二維示例
matrix = np.array([[1, 2], [3, 4], [5, 6]])
print(matrix[matrix > 3]) # [4 5 6]
✅ 布爾索引常用於數據清洗、條件賦值等場景。
三、修改數組元素
1. 基本索引賦值(影響原數組)
a = np.array([1, 2, 3])
a[0] = 99
print(a) # [99 2 3]
2. 切片賦值
a[1:] = 0
print(a) # [99 0 0]
3. 布爾索引賦值
b = np.array([1, 2, 3, 4, 5])
b[b > 3] = -1
print(b) # [1 2 3 -1 -1]
4. 花式索引賦值
c = np.array([10, 20, 30, 40])
c[[0, 2]] = [99, 88]
print(c) # [99 20 88 40]
四、特殊索引技巧
1. np.newaxis 或 None:增加維度
x = np.array([1, 2, 3])
print(x.shape) # (3,)
y = x[:, np.newaxis] # 列向量
print(y.shape) # (3, 1)
# [[1]
# [2]
# [3]]
2. np.where():條件索引
arr = np.array([1, 2, 3, 4, 5])
indices = np.where(arr > 3) # 返回滿足條件的索引元組
print(indices) # (array([3, 4]),)
print(arr[indices]) # [4 5]
# 也可用於三元選擇
result = np.where(arr > 3, arr, 0) # 滿足條件保留,否則設為0
# [0 0 0 4 5]
五、注意事項與常見陷阱
| 問題 | 説明 |
|---|---|
| 視圖 vs 副本 | 基本切片返回視圖;高級索引返回副本 |
| 維度丟失 | arr[0] 對二維數組返回一維,若想保持二維用 arr[0:1] |
| 越界錯誤 | 索引超出範圍會報 IndexError |
| 負步長切片 | a[::-1] 安全,但 a[3:0:-1] 不包含索引0 |
| 混合索引 | arr[1, [0,2]] 是合法的(基本+高級混合) |
六、小結:索引方式對比
| 索引類型 | 示例 | 返回 | 是否修改原數組 |
|---|---|---|---|
| 基本索引 | arr[1], arr[1:3] |
視圖 | 是 |
| 花式索引 | arr[[1,3]] |
副本 | 否 |
| 布爾索引 | arr[arr>0] |
副本 | 否 |
| 多維混合 | arr[1, [0,2]] |
副本 | 否 |
掌握這些索引與切片技巧,你就能高效地提取、篩選和修改 NumPy 數組中的數據,為數據分析、圖像處理、機器學習等任務打下堅實基礎。
後續
部分代碼已經上傳至gitee,後續會逐步更新,主要受時間原因限制,當然自己也可以克隆到本地學習拓展。
資料關注
公眾號:咚咚王 gitee:https://gitee.com/wy18585051844/ai_learning
《Python編程:從入門到實踐》 《利用Python進行數據分析》 《算法導論中文第三版》 《概率論與數理統計(第四版) (盛驟) 》 《程序員的數學》 《線性代數應該這樣學第3版》 《微積分和數學分析引論》 《(西瓜書)周志華-機器學習》 《TensorFlow機器學習實戰指南》 《Sklearn與TensorFlow機器學習實用指南》 《模式識別(第四版)》 《深度學習 deep learning》伊恩·古德費洛著 花書 《Python深度學習第二版(中文版)【純文本】 (登封大數據 (Francois Choliet)) (Z-Library)》 《深入淺出神經網絡與深度學習+(邁克爾·尼爾森(Michael+Nielsen)》 《自然語言處理綜論 第2版》 《Natural-Language-Processing-with-PyTorch》 《計算機視覺-算法與應用(中文版)》 《Learning OpenCV 4》 《AIGC:智能創作時代》杜雨+&+張孜銘 《AIGC原理與實踐:零基礎學大語言模型、擴散模型和多模態模型》 《從零構建大語言模型(中文版)》 《實戰AI大模型》 《AI 3.0》