在 NumPy 中,數組(ndarray)中的數據通常需要通過索引(indexing)和切片(slicing)進行訪問或修改。索引機制不僅決定了如何獲取數組中的元素,也直接影響數據是否共享內存以及運算效率。
NumPy 的索引機制在繼承 Python 序列(如列表和字符串)索引規則的基礎上進行了擴展,使其能夠高效地處理多維數組、條件篩選以及復雜的數據選擇。
在 NumPy 中,數組索引通常可以分為兩大類:
(1)基本索引(Basic Indexing)
? 整數索引
? 切片訪問
? 多維數組的整數索引
? 維度擴展
? 省略符
(2)高級索引(Advanced Indexing)
? 整數數組索引
? 布爾數組索引
在實際使用中,兩者也可以同時出現在同一表達式中,這種情況通常稱為混合索引(Mixed Indexing)。
一、基本索引
基本索引是 NumPy 中最基礎的數組訪問方式,其行為與 Python 序列類型(如列表、)的索引和切片規則基本一致。
1、整數索引
整數索引用于訪問數組中的單個元素。
示例:
# 10說明:a[0] 表示訪問數組中的第一個元素。
NumPy 也支持負索引,用于從數組末尾開始訪問。
示例:
# 40說明:-1 表示最后一個元素,-2 表示倒數第二個元素,如此類推。
提示:
當整數索引用于定位單個元素時,返回結果通常是 NumPy 標量(scalar),而不是數組對象。
2、切片訪問
切片用于訪問數組中的一段連續元素。
語法結構:
array[start:stop:step]含義:
? start:起始位置(包含)
? stop:結束位置(不包含)
? step:步長
示例:
# [20 30 40]說明:返回索引 1 到 3 的元素。
切片參數可以省略。
示例:
# [10 30 50]也可以通過負步長實現數組反向。
示例:
# [50 40 30 20 10]說明:[::-1] 是數組反轉的常見寫法。
3、多維數組索引
對于多維數組,需要使用逗號分隔各個維度的索引。
(1)訪問單個元素
# 2說明:a[0,1] 表示第 0 行第 1 列的元素。
(2)訪問整行
# [4 5 6]a[1] 表示取第 1 行數據。對普通 ndarray 而言,這種基本索引通常返回原數組上的一個一維視圖。
或者:
# [4 5 6](3)訪問整列
# [2 5]: 表示該維度的全部元素。
(4)子數組切片
示例:
print(a[0:2, 1:3])輸出:
[5 6]]0:2 表示選擇前兩行,1:3 表示選擇第 2、3 列。
4、基本索引的維度規則
在 NumPy 的基本索引中,不同類型的索引對象會對數組維度產生不同影響。
(1)整數索引
會定位該維度上的一個元素,并消除該維度。
(2)切片訪問
會選擇該維度上的一段范圍,并保留該維度。
示例:
print(a[0:1].shape) # (1,3,4)a[0] 使用整數索引,因此第 0 維被消除。
a[0:1] 使用切片訪問,因此第 0 維被保留。
在基本索引中,整數索引會消除該維度,而切片訪問會保留該維度。
(3)維度擴展
np.newaxis 是一個特殊對象(等價于 None),其本質是在索引表達式中插入長度為 1 的新維度。它通常只在索引語法中使用,而不是作為數組函數調用。
示例:
print(a[:, np.newaxis])輸出:
[3]]數組形狀從 (3,) 變為 (3,1)。
(4)省略符
省略符(ellipsis) ... 用于表示若干個連續維度,等價于使用多個 : 展開。
示例:
print(a[..., 0])相當于:
a[:, :, 0]要注意的是,一個索引表達式中通常只能出現一個省略符。
5、基本切片通常返回視圖
基本索引通常返回原數組的視圖(view),即新數組與原數組共享同一塊內存,而不是數據副本,這意味著修改結果可能會影響原數組。
示例:
# [ 1 99 3 4]提示:
修改切片內容會影響原數組。若希望切片結果與原數組徹底分離,應對切片結果調用 .copy():
b = a[1:3].copy()二、高級索引
當索引表達式中包含以下對象時,NumPy 會啟用高級索引(也稱“花式索引” fancy indexing):
? 整數數組
? 布爾數組
與基本索引不同,高級索引具有兩個重要特點:
(1)可以選擇不連續元素
(2)基本索引通常返回視圖(view),而高級索引的取值結果始終是副本(copy)
1、整數數組索引
NumPy 支持使用整數數組索引來一次訪問多個指定位置的元素。
(1)一維數組的整數數組索引
示例:
# [10 30 40]或者:
print(a[[0, 2, 3]])說明: 整數數組 [0,2,3] 指定需要訪問的元素位置。
(2)多維數組的整數數組索引
每個維度使用一個整數數組索引,維度之間用逗號分隔。
示例:
# [2 5]或者:
print(a[[0, 2],[1, 0]])說明:輸出的對應元素是 a[0,1] 和 a[2,0]。
2、布爾數組索引
布爾索引用一個布爾數組作為篩選條件,True 位置對應的元素將被選擇。
布爾索引要求布爾數組與被索引部分的形狀相匹配。
例如,對一維數組進行布爾篩選時,布爾數組長度必須與原數組長度一致;對多維數組某一軸進行篩選時,布爾數組長度必須與該軸長度一致。若形狀不匹配,NumPy 會拋出錯誤。
示例:
# [4 5]或者直接使用條件表達式:
print(a[a > 3])a > 3 會構建一個布爾數組:
[False, False, False, True, True]a[a > 3] 則只返回條件為 True 的元素。
也可直接使用自定義的布爾數組:
print(a[[False, False, False, True, True]])NumPy 使用 &(按位與)和 |(按位或)進行邏輯運算,以實現多條件篩選。
示例:
# [3 4 5]其實質是兩個布爾數組進行邏輯運算后得到一個新的布爾數組作為條件篩選的依據。
當使用與原數組同形狀的布爾數組進行篩選時,結果通常會以一維數組的形式返回所有滿足條件的元素。
提示:
? 對數組條件進行組合時,應使用 & 和 |,而不能使用 Python 的 and 和 or
? 多個條件表達式必須使用括號包裹
三、混合索引
當基本索引與高級索引同時出現在同一個索引表達式中時,就形成了混合索引。
示例:
print(a[:, [1, 3]])輸出:
[ 9 11]]解釋:
此處的 : 為基本索引切片,表示選擇第 0 維度的全部元素(所有行)。而 [1,3] 為整數數組索引,表示在第 1 維度(列維度)選擇第 1 列和第 3 列。因此這是一個混合索引。
在混合索引中,只要索引表達式中包含高級索引(整數數組或布爾數組),NumPy 就會啟用高級索引機制,并返回新的數組副本。
因此,a[:, [1,3]] 的返回值是 copy,而不是 view。
需要注意的是,在更復雜的混合索引中,高級索引參與結果形狀的方式可能并不完全符合初學者的直覺,因此在多維數組場景下,最好通過 shape 明確檢查結果結構。
四、索引與切片相關函數
NumPy 提供了一組用于數組索引與元素選擇的函數,可在多維數組中高效定位、篩選和提取數據。
? 獲取元素的索引:argmax()、argmin()、argwhere()、nonzero()
? 條件篩選與元素選擇:where()
? 根據索引或條件提取數組元素:take()、choose()、take_along_axis()、compress()、extract()
? 在線性索引與多維坐標之間進行轉換:unravel_index()、ravel_multi_index()
? 訪問與計算數組的對角線元素:diagonal() 、trace()
這些函數共同構成了 NumPy 數組數據訪問與選擇的重要工具。
詳情請參閱:
小結
NumPy 的索引機制使數組數據能夠以靈活而高效的方式被訪問和選擇。通過整數索引、切片、條件篩選以及多維索引表達式,可以精確地定位數組中的元素或子數組。需要注意的是,不同索引方式在內存行為上存在差異:有些操作返回原數組的視圖,有些則生成新的數據副本。理解這些規則,是正確處理數組數據與避免隱式數據修改的重要基礎。
“點贊有美意,贊賞是鼓勵”
特別聲明:以上內容(如有圖片或視頻亦包括在內)為自媒體平臺“網易號”用戶上傳并發布,本平臺僅提供信息存儲服務。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.