高級(jí)索引
Numpy 比一般的 Python 序列提供更多的索引方式。除了前面章節(jié)介紹的用整數(shù)和切片的索引外,本節(jié)深入介紹布爾型索引和花式索引。
1. 布爾型索引
在前面的章節(jié),我們簡單介紹了,可以通過一個(gè)布爾數(shù)組來索引目標(biāo)數(shù)組。
1.1 比較運(yùn)算符與布爾型數(shù)組
在實(shí)際使用中,可以通過比較運(yùn)算符來產(chǎn)生一個(gè)布爾型數(shù)組。
案例
利用random模塊產(chǎn)生一個(gè)大小為7×4的隨機(jī)數(shù)數(shù)組:
data = np.random.randn(7,4)
data
out:
array([[-0.79578969, -0.73156773, 0.60648318, -0.57213653],
[ 0.03461754, -0.91921724, -1.51730244, 0.68583205],
[-0.0584198 , -0.92494003, -0.08106442, -1.44821654],
[-0.76501214, 2.01128245, 1.0350961 , 0.81014769],
[-0.71850433, -1.613115 , -0.23420344, 0.61378525],
[-1.06667762, 1.11845542, 1.68075202, 0.25989931],
[-0.80773979, -0.37137009, 0.45941405, -0.57604566]])
定義一個(gè)名稱數(shù)組,長度為7,并假設(shè)上述data中的每一行與名稱數(shù)組中的名字一一對應(yīng)。
names = np.array(['Ben','Tom','Ben','Jeremy','Jeremy','Tom','Ben'])
names
out:
array(['Ben', 'Tom', 'Ben', 'Jeremy', 'Jeremy', 'Tom', 'Ben'], dtype='<U6')
對data數(shù)組,通過傳入一個(gè)比較運(yùn)算符,可以與全部元素逐一比較:
data > 0
out:
array([[False, False, True, False],
[ True, False, False, True],
[False, False, False, False],
[False, True, True, True],
[False, False, False, True],
[False, True, True, True],
[False, False, True, False]])
對同樣大小的布爾型數(shù)組,可以利用&(和)、|(或)、-(非)進(jìn)行運(yùn)算。
例如對data進(jìn)行-1~1之間的判斷:
(data>-1) & (data < 1)
out:
array([[ True, True, True, True],
[ True, True, False, True],
[ True, True, True, False],
[ True, False, False, True],
[ True, False, True, True],
[False, False, False, True],
[ True, True, True, True]])
1.2 比較運(yùn)算符與布爾型索引
先利用比較運(yùn)算符創(chuàng)建布爾型數(shù)組,再利用布爾型索引的功能,可以快速進(jìn)行篩選。
案例
names中的每一個(gè)名字,和data的每一行是一一對應(yīng)的關(guān)系。因此可以快速地選擇出Ben的相關(guān)信息:
data[names=='Ben']
out:
array([[-0.79578969, -0.73156773, 0.60648318, -0.57213653],
[-0.0584198 , -0.92494003, -0.08106442, -1.44821654],
[-0.80773979, -0.37137009, 0.45941405, -0.57604566]])
利用‘&’運(yùn)算符,一次性選擇出Ben和Tom的相關(guān)信息
data[(names=='Ben') | (names=='Tom')]
out:
array([[-0.79578969, -0.73156773, 0.60648318, -0.57213653],
[ 0.03461754, -0.91921724, -1.51730244, 0.68583205],
[-0.0584198 , -0.92494003, -0.08106442, -1.44821654],
[-1.06667762, 1.11845542, 1.68075202, 0.25989931],
[-0.80773979, -0.37137009, 0.45941405, -0.57604566]])
布爾型數(shù)組也可以和切片、整數(shù)索引混合使用:
array([[-0.79578969, -0.73156773],
[ 0.03461754, -0.91921724],
[-0.0584198 , -0.92494003],
[-1.06667762, 1.11845542],
[-0.80773979, -0.37137009]])
特別地,也可以利用data本身,快速選擇出大于0的元素:
data[data > 0]
out:
array([0.60648318, 0.03461754, 0.68583205, 2.01128245, 1.0350961 ,
0.81014769, 0.61378525, 1.11845542, 1.68075202, 0.25989931,
0.45941405])
這里選擇的結(jié)果是以一維數(shù)組的形式返回的。
2. 花式索引
花式索引是一個(gè)Numpy術(shù)語,是指利用整數(shù)數(shù)組進(jìn)行索引。
2.1 使用一維整型數(shù)組作為索引
對于使用一維整型數(shù)組作為索引,如果目標(biāo)是一維數(shù)組,那么索引的結(jié)果就是對應(yīng)位置的元素;如果目標(biāo)是二維數(shù)組,那么就是對應(yīng)下標(biāo)的行。
案例
對于上述案例中的names數(shù)組,通過傳入一個(gè)特定順序的整數(shù)列表(或ndarray),來按照指定順序選取元素:
names[[4,3,2,1]]
out:
array(['Jeremy', 'Jeremy', 'Ben', 'Tom'], dtype='<U6')
如果使用負(fù)數(shù),則會(huì)從末尾開始選取:
names[[-1,-2,-3,-4]]
out:
array(['Ben', 'Tom', 'Jeremy', 'Jeremy'], dtype='<U6')
案例
同樣地,對data二維數(shù)組,通過傳入特定順序的整數(shù)列表,來按照指定順序選取行:
data[[3,1]]
out:
array([[-0.76501214, 2.01128245, 1.0350961 , 0.81014769],
[ 0.03461754, -0.91921724, -1.51730244, 0.68583205]])
2.2 傳入多組索引序列
一次性傳入多個(gè)索引數(shù)組,這種情況會(huì)有一些特殊,其返回的是一個(gè)一維數(shù)組,其中的元素對應(yīng)各個(gè)索引元祖。
案例
data[[3,1,2],[0,2,1]]
out:
array([-0.76501214, -1.51730244, -0.92494003])
一次性傳入兩個(gè)列表:[3,1,2]、[0,2,1],最終選取出三個(gè)元素,其在data數(shù)組中的位置分別是(3, 0)、(1, 2)、(2, 1)。并沒有和切片索引一樣,返回一個(gè)矩形區(qū)域。
那么如何能夠索引矩形區(qū)域呢?
案例
下面是得到矩形區(qū)域的一個(gè)這種的辦法:
data[[3,1,2]][:,[0,2,1]]
out:
array([[-0.76501214, 1.0350961 , 2.01128245],
[ 0.03461754, -1.51730244, -0.91921724],
[-0.0584198 , -0.08106442, -0.92494003]])
另外,需要記住一個(gè)結(jié)論是:花式索引和切片不一樣,它總是將數(shù)據(jù)復(fù)制到一個(gè)新的數(shù)組中。
3. 小結(jié)
本節(jié)介紹了兩種較為復(fù)雜的索引:布爾型索引和花式索引。布爾型索引中,通過與比較運(yùn)算符連用,可以快速基于判斷邏輯,篩選出指定數(shù)據(jù)?;ㄊ剿饕齽t是一種應(yīng)用不多,但是較為特殊的索引,需要了解。