Numpy 的索引與切片
Python 的內(nèi)置容器對(duì)象,例如列表,可以通過索引或切片來訪問和修改。這在 ndarray 對(duì)象中也一樣,ndarray 對(duì)象中的元素遵循基于零的索引,常用的索引方式:元素訪問、切片索引、布爾型索引。
1. 元素訪問
1.1 單一元素訪問
一維數(shù)組的元素訪問非常簡單,和 Python 列表規(guī)則基本差不多。對(duì)單一元素的訪問,索引遵循從 0 開始,依次遞增 1。
案例
例如,對(duì)于創(chuàng)建的一維數(shù)組,我們?cè)L問第5個(gè)元素對(duì)象:
arr = np.arange(10)
arr
Out:
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
arr[4]
Out:
4
也可以用負(fù)數(shù)從末位開始對(duì)數(shù)組反向索引,例如-1表示末位元素:
arr[-1]
Out:
9
2. 切片索引
2.1 基本切片
跟列表類似,你可以一次性多個(gè)索引位置,進(jìn)行多元素的訪問。如果索引位置是離散的,可以手動(dòng)構(gòu)造列表切片的形式傳入。也可以利用 start、stop、step
的方式來生成切片器。
案例
對(duì)于上述創(chuàng)建的一位數(shù)組,我們同時(shí)訪問首尾的元素,那么可以指定其索引位置0和-1,語法如下:
arr[[0, -1]]
Out:
array([0, 9])
這種情況下,訪問結(jié)果會(huì)重新構(gòu)造為ndarray對(duì)象返回。
對(duì)于有規(guī)律的訪問,可以構(gòu)造相應(yīng)的切片器,例如我們?cè)L問上述數(shù)組中的偶數(shù)元素:
arr[0: -1: 2]
Out:
array([0, 2, 4, 6, 8])
需要注意的是,在上述構(gòu)造的切片器中,最后一位索引序列是無法取到的。例如我們?cè)L問奇數(shù)元素:
arr[1: -1: 2]
Out:
array([1, 3, 5, 7])
arr[1: : 2]
Out:
array([1, 3, 5, 7, 9])
對(duì)比發(fā)現(xiàn),當(dāng)切片器指定了 -1 時(shí),末位元素是不會(huì)被選中的。
2.2 多維數(shù)組切片索引
對(duì)于二維數(shù)組,在某些特殊情況下,可以通過連續(xù)切片的方式進(jìn)行訪問。
案例
例如,我們創(chuàng)建一個(gè)連續(xù)整數(shù)組成的方陣:
arr_2d = np.arange(16).reshape(4,4)
Out:
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[12, 13, 14, 15]])
對(duì) arr_2d
構(gòu)造一個(gè)連續(xù)切片:
arr_2d[0][1:3]
Out:
array([1, 2])
對(duì)多維數(shù)組的索引,想要達(dá)到同樣的的效果,可以一次傳入多個(gè)切片。例如對(duì)上述結(jié)果,可以修改為:
arr_2d[0, 1:3]
Out:
array([1, 2])
在上述步驟中,傳入了 2 個(gè)切片。嚴(yán)格來講,第一個(gè)切片是整數(shù)索引,是對(duì)數(shù)組的最外層(axis=0
)進(jìn)行選擇;第二個(gè)切片是對(duì)數(shù)組的內(nèi)一層(axis=1
)進(jìn)行選擇。
更一般地,我們可以自由地根據(jù)需求,構(gòu)造想要的切片效果。例如:
arr_2d[0:2, 1:3]
Out:
array([[1, 2],
[5, 6]])
上述案例在 axis=0
方向上選擇了第 0 和第 1 行,在 axis=1
方向上選擇了第 1 列和第 2 列,兩種切片方向的聚焦部分即為切片索引的結(jié)果。
需要指出的是,如果切片只有冒號(hào),表示選取該方向的整個(gè)軸。例如,利用該方法,可以對(duì)二維數(shù)組進(jìn)行列方向的切片:
arr_2d[:, 1:3]
Out:
array([[ 1, 2],
[ 5, 6],
[ 9, 10],
[13, 14]])
上述案例實(shí)現(xiàn)了選擇第一列和第二列的效果。
3. 布爾型索引
直觀上理解,通過布爾類型來完成索引的過程,我們可以稱之為布爾型索引。
案例
例如對(duì)于上述 arr_2d
,我們通過傳入 [True, True, False, False]
這樣一個(gè)布爾類型的列表,來選擇第 0 行和第 1 行:
arr_2d[[True, True, False, False]]
Out:
array([[0, 1, 2, 3],
[4, 5, 6, 7]])
需要注意的是,傳入的布爾類型列表的長度,需要跟被索引的軸的長度一致,否則會(huì)引起 IndexError
。在實(shí)際使用中,可以靈活地把布爾索引和切片索引、整數(shù)索引混合使用,非常方便。
例如,這里利用布爾型索引和切片索引來達(dá)到列方向切片的效果:
arr_2d[:, [True, True, False, False]]
Out:
array([[ 0, 1],
[ 4, 5],
[ 8, 9],
[12, 13]])