Numpy的布爾索引與花式索引

目錄

  • 布爾索引
  • 花式索引 (Fancy Indexing)
  • 二者的聯(lián)系?

申明:本文中提到的數(shù)組就是特指numpy的數(shù)據(jù)結(jié)構(gòu)ndarray础芍,同理旗闽,一維數(shù)組或者N維數(shù)組,也是指一維活著N維ndarray鲸郊。

參考資料:
(https://docs.scipy.org/doc/numpy/reference/arrays.indexing.html#indexing)
Python for Data Analysis 2nd Edition

布爾索引

我們可以通過(guò)一個(gè)布爾數(shù)組來(lái)索引目標(biāo)數(shù)組,以此找出與布爾數(shù)組中值為T(mén)rue的對(duì)應(yīng)的目標(biāo)數(shù)組中的數(shù)據(jù)(后面通過(guò)實(shí)例可清晰的觀察)货邓。需要注意的是秆撮,布爾數(shù)組的長(zhǎng)度必須與目標(biāo)數(shù)組對(duì)應(yīng)的軸的長(zhǎng)度一致。下面通過(guò)幾個(gè)例子來(lái)說(shuō)明换况。

一維數(shù)組的索引

布爾數(shù)組中职辨,下標(biāo)為0,3,4的位置是True,因此將會(huì)取出目標(biāo)數(shù)組中對(duì)應(yīng)位置的元素戈二。

In [24]: arr = np.arange(7)

In [25]: booling1 = np.array([True,False,False,True,True,False,False])

In [26]: arr[booling1]
Out[26]: array([0, 3, 4])
二維數(shù)組的索引

布爾數(shù)組中舒裤,下標(biāo)為0,3,4的位置是True,因此將會(huì)取出目標(biāo)數(shù)組中第0,3,4行觉吭。

In [27]: arr = np.arange(28).reshape((7,4))

In [28]: arr
Out[28]: 
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11],
       [12, 13, 14, 15],
       [16, 17, 18, 19],
       [20, 21, 22, 23],
       [24, 25, 26, 27]])

In [29]: booling1 = np.array([True,False,False,True,True,False,False])

In [30]: arr[booling1]
Out[30]: 
array([[ 0,  1,  2,  3],
       [12, 13, 14, 15],
       [16, 17, 18, 19]])

我們還可以通過(guò)數(shù)組的邏輯運(yùn)算來(lái)作為索引(實(shí)際上數(shù)組的邏輯運(yùn)算的結(jié)果腾供,也就是一個(gè)布爾數(shù)組)。假設(shè)我們有一個(gè)長(zhǎng)度為7的字符串?dāng)?shù)組,然后對(duì)這個(gè)字符串?dāng)?shù)組進(jìn)行邏輯運(yùn)算台腥,進(jìn)而把元素的結(jié)果(布爾數(shù)組)作為索引的條件傳遞給目標(biāo)數(shù)組(本質(zhì)上,和上面那個(gè)例子是類(lèi)似的)绒北。例如黎侈,還是上面例子中的數(shù)組arr,現(xiàn)在就胡亂想象成每一行數(shù)據(jù)是一個(gè)人的一個(gè)月其中四天賺的錢(qián)闷游。這7行中峻汉,可能有某些行屬于特定的人,那就想象成不同月份賺到的錢(qián)脐往。

In [35]: names = np.array(['Ben','Tom','Ben','Jeremy','Jason','Michael','Ben'])

In [36]: names == 'Ben'
Out[36]: array([ True, False,  True, False, False, False,  True], dtype=bool)

# 找出Ben賺的錢(qián)的明細(xì)
In [37]: arr[names == 'Ben']
Out[37]: 
array([[ 0,  1,  2,  3],
       [ 8,  9, 10, 11],
       [24, 25, 26, 27]])

# 在此基礎(chǔ)上休吠,我們還可以添加常規(guī)的索引和切片操作
In [38]: arr[names == 'Ben',3]
Out[38]: array([ 3, 11, 27])

In [39]: arr[names == 'Ben',1:4]
Out[39]: 
array([[ 1,  2,  3],
       [ 9, 10, 11],
       [25, 26, 27]])

上面的例子,通過(guò)邏輯運(yùn)算把屬于Ben的明細(xì)找了出來(lái)业簿。那如果我們想查找不屬于Ben的明細(xì)瘤礁,則可以通過(guò)!=或者~運(yùn)算。這種邏輯運(yùn)算梅尤,還可以用來(lái)做數(shù)據(jù)清洗柜思,后面會(huì)介紹到。

In [40]: arr[names!='Ben']
Out[40]: 
array([[ 4,  5,  6,  7],
       [12, 13, 14, 15],
       [16, 17, 18, 19],
       [20, 21, 22, 23]])

In [41]: arr[~(names=='Ben')]
Out[41]: 
array([[ 4,  5,  6,  7],
       [12, 13, 14, 15],
       [16, 17, 18, 19],
       [20, 21, 22, 23]])

多個(gè)邏輯運(yùn)算的與和或也是支持的巷燥。例如赡盘,找出Tom或者Jason的明細(xì),并且想對(duì)他們殘忍點(diǎn)缰揪,把他們的錢(qián)都清零陨享。

In [44]: arr[(names == 'Jason') | (names == 'Tom')]
Out[44]: 
array([[ 4,  5,  6,  7],
       [16, 17, 18, 19]])

In [45]: arr[(names == 'Jason') | (names == 'Tom')] = 0

In [46]: arr
Out[46]: 
array([[ 0,  1,  2,  3],
       [ 0,  0,  0,  0],
       [ 8,  9, 10, 11],
       [12, 13, 14, 15],
       [ 0,  0,  0,  0],
       [20, 21, 22, 23],
       [24, 25, 26, 27]])

除此之外,我們也可以目標(biāo)數(shù)組上做邏輯運(yùn)算钝腺。實(shí)際上抛姑,這種邏輯運(yùn)算的到的結(jié)果是和目標(biāo)數(shù)組維度和長(zhǎng)度都一樣的布爾數(shù)組。例如拍屑,找出arr中大于15的元素途戒,與上面的例子不一樣,這個(gè)例子返回的結(jié)果是一個(gè)一維數(shù)組僵驰。

In [51]: arr[arr>15]
Out[51]: array([16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27])

借上面的例子引申一下喷斋,假設(shè)現(xiàn)在想把上述數(shù)組中,小于或者等于15的數(shù)歸零蒜茴,類(lèi)似于數(shù)據(jù)清洗星爪,那么可以通過(guò)下面的方式。

In [139]: arr
Out[139]: 
array([[ 0,  1,  2,  3,  4,  5,  6],
       [ 7,  8,  9, 10, 11, 12, 13],
       [14, 15, 16, 17, 18, 19, 20],
       [21, 22, 23, 24, 25, 26, 27]])

In [140]: arr[arr<=15]=0

In [141]: arr
Out[141]: 
array([[ 0,  0,  0,  0,  0,  0,  0],
       [ 0,  0,  0,  0,  0,  0,  0],
       [ 0,  0, 16, 17, 18, 19, 20],
       [21, 22, 23, 24, 25, 26, 27]])

花式索引 (Fancy Indexing)

花式索引是NumPy用來(lái)描述使用整型數(shù)組(這里的數(shù)組粉私,可以是NumPy的數(shù)組顽腾,也可以是python自帶的list)作為索引的術(shù)語(yǔ),其意義是根據(jù)索引數(shù)組的值作為目標(biāo)數(shù)組的某個(gè)軸的下標(biāo)來(lái)取值。對(duì)于使用一維整型數(shù)組作為索引抄肖,如果目標(biāo)是一維數(shù)組久信,那么索引的結(jié)果就是對(duì)應(yīng)位置的元素;如果目標(biāo)是二維數(shù)組漓摩,那么就是對(duì)應(yīng)下標(biāo)的行裙士。

In [69]: arr = np.array(['zero','one','two','three','four'])

In [70]: arr[[1,4]]
Out[70]: 
array(['one', 'four'],
      dtype='<U5')
      

In [71]: arr = np.empty((8,4),dtype=np.int)

In [72]: for i in range(8):
    ...:     arr[i] = i
    ...:     

In [73]: arr
Out[73]: 
array([[0, 0, 0, 0],
       [1, 1, 1, 1],
       [2, 2, 2, 2],
       [3, 3, 3, 3],
       [4, 4, 4, 4],
       [5, 5, 5, 5],
       [6, 6, 6, 6],
       [7, 7, 7, 7]])
In [75]: arr[[4,3,0,6]]
Out[75]: 
array([[4, 4, 4, 4],
       [3, 3, 3, 3],
       [0, 0, 0, 0],
       [6, 6, 6, 6]])

In [76]: arr[[-3,-5,-7]]
Out[76]: 
array([[5, 5, 5, 5],
       [3, 3, 3, 3],
       [1, 1, 1, 1]])

對(duì)于使用兩個(gè)整型數(shù)組作為索引的時(shí)候,那么結(jié)果是按照順序取出對(duì)應(yīng)軸的對(duì)應(yīng)下標(biāo)的值管毙。特別注意腿椎,這兩個(gè)整型數(shù)組的shape應(yīng)該一致,或者其中一個(gè)數(shù)組應(yīng)該是長(zhǎng)度為1的一維數(shù)組(與NumPy的Broadcasting機(jī)制于關(guān)系)夭咬。例如啃炸,以[1,3,5],[2,4,6]這兩個(gè)整型數(shù)組作為索引,那么對(duì)于二維數(shù)組卓舵,則取出(1,2),(3,4),(5,6)這些坐標(biāo)對(duì)應(yīng)的元素南用。

In [77]: arr = np.arange(42).reshape(6,7)

In [78]: arr
Out[78]: 
array([[ 0,  1,  2,  3,  4,  5,  6],
       [ 7,  8,  9, 10, 11, 12, 13],
       [14, 15, 16, 17, 18, 19, 20],
       [21, 22, 23, 24, 25, 26, 27],
       [28, 29, 30, 31, 32, 33, 34],
       [35, 36, 37, 38, 39, 40, 41]])

In [79]: arr[[1,3,5],[2,4,6]]
Out[79]: array([ 9, 25, 41])

二者的聯(lián)系?

個(gè)人的猜想是边器,布爾索引和花式索引之間训枢,是有聯(lián)系的。竊以為布爾索引是通過(guò)花式索引來(lái)實(shí)現(xiàn)的(雖然不100%確定忘巧,但是我個(gè)人感覺(jué)可以這么理解恒界。各位請(qǐng)自行判斷)。為什么這么說(shuō)砚嘴?先來(lái)看看官方的文檔對(duì)布爾索引的說(shuō)明:

Boolean array indexing
A single boolean index array is practically identical to x[obj.nonzero()]

上面的意思十酣,不就是說(shuō)x[obj]是等價(jià)x[obj.nonzero()](這里obj是一個(gè)布爾數(shù)組)。我們來(lái)驗(yàn)證一下:

In [112]: arr = np.arange(12).reshape(3,4)

In [113]: i = np.array([True,False,True])

In [114]: i.nonzero()
Out[114]: (array([0, 2]),)

In [115]: arr[i]
Out[115]: 
array([[ 0,  1,  2,  3],
       [ 8,  9, 10, 11]])

In [116]: arr[i.nonzero()]
Out[116]: 
array([[ 0,  1,  2,  3],
       [ 8,  9, 10, 11]])

通過(guò)以上例子可知大概的關(guān)系:arr[i] <=> arr[i.nonzero()] => arr[(array([0,2]),)] => arr[array([0,2]),] => arr[[0,2]](到此為止就是花式索引了)际长。在來(lái)看一個(gè)復(fù)雜點(diǎn)的例子:

In [131]: i
Out[131]: array([ True, False,  True], dtype=bool)

In [132]: j
Out[132]: array([ True,  True, False, False], dtype=bool)

In [133]: i.nonzero()
Out[133]: (array([0, 2]),)

In [134]: j.nonzero()
Out[134]: (array([0, 1]),)

In [135]: arr[i,j]
Out[135]: array([0, 9])

# 這里不大清楚耸采,為什么結(jié)果是一個(gè)二維數(shù)組
In [136]: arr[i.nonzero(),j.nonzero()]
Out[136]: array([[0, 9]])

In [137]: arr[[0,2],[0,1]]
Out[137]: array([0, 9])
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市工育,隨后出現(xiàn)的幾起案子虾宇,更是在濱河造成了極大的恐慌,老刑警劉巖如绸,帶你破解...
    沈念sama閱讀 206,839評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件嘱朽,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡怔接,警方通過(guò)查閱死者的電腦和手機(jī)搪泳,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)扼脐,“玉大人,你說(shuō)我怎么就攤上這事〖柙蓿” “怎么了佣谐?”我有些...
    開(kāi)封第一講書(shū)人閱讀 153,116評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵台谍,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我吁断,道長(zhǎng)坞生,這世上最難降的妖魔是什么仔役? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,371評(píng)論 1 279
  • 正文 為了忘掉前任是己,我火速辦了婚禮又兵,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘卒废。我一直安慰自己沛厨,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,384評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布摔认。 她就那樣靜靜地躺著逆皮,像睡著了一般。 火紅的嫁衣襯著肌膚如雪参袱。 梳的紋絲不亂的頭發(fā)上电谣,一...
    開(kāi)封第一講書(shū)人閱讀 49,111評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音抹蚀,去河邊找鬼剿牺。 笑死,一個(gè)胖子當(dāng)著我的面吹牛环壤,可吹牛的內(nèi)容都是我干的晒来。 我是一名探鬼主播,決...
    沈念sama閱讀 38,416評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼郑现,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼湃崩!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起懂酱,我...
    開(kāi)封第一講書(shū)人閱讀 37,053評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤竹习,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后列牺,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體整陌,經(jīng)...
    沈念sama閱讀 43,558評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,007評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了泌辫。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片随夸。...
    茶點(diǎn)故事閱讀 38,117評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖震放,靈堂內(nèi)的尸體忽然破棺而出宾毒,到底是詐尸還是另有隱情,我是刑警寧澤殿遂,帶...
    沈念sama閱讀 33,756評(píng)論 4 324
  • 正文 年R本政府宣布诈铛,位于F島的核電站,受9級(jí)特大地震影響墨礁,放射性物質(zhì)發(fā)生泄漏幢竹。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,324評(píng)論 3 307
  • 文/蒙蒙 一恩静、第九天 我趴在偏房一處隱蔽的房頂上張望焕毫。 院中可真熱鬧,春花似錦驶乾、人聲如沸邑飒。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,315評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至罕扎,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間丐重,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,539評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工扮惦, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人崖蜜。 一個(gè)月前我還...
    沈念sama閱讀 45,578評(píng)論 2 355
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像豫领,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子等恐,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,877評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容