numpy中索引和切片詳解
索引和切片
一維數(shù)組
一維數(shù)組很簡(jiǎn)單,基本和列表一致。
它們的區(qū)別在于數(shù)組切片是原始數(shù)組視圖(這就意味著,如果做任何修改,原始都會(huì)跟著更改)。
這也意味著,如果不想更改原始數(shù)組,我們需要進(jìn)行顯式的復(fù)制,從而得到它的副本(.copy())。
import numpy as np #導(dǎo)入numpy arr = np.arange(10) #類似于list的range() arr Out[3]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) arr[4] #索引(注意是從0開(kāi)始的) Out[4]: 4 arr[3:6] #切片 Out[6]: array([3, 4, 5]) arr_old = arr.copy() #先復(fù)制一個(gè)副本 arr_old Out[8]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) arr[3:6] = 33 arr #可以發(fā)現(xiàn)將標(biāo)量賦值給一個(gè)切片時(shí),該值可以傳播到整個(gè)選區(qū) Out[10]: array([ 0, 1, 2, 33, 33, 33, 6, 7, 8, 9]) arr_old Out[11]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
二維數(shù)組
二維數(shù)組中,各索引位置上的元素不再是標(biāo)量,而是一維數(shù)組(好像很難理解哈)。
arr1 = np.array([[1, 2, 3],[4, 5, 6],[7, 8, 9]]) arr1[0] Out[13]: array([1, 2, 3]) arr1[1,2] Out[14]: 6
好像很難理解,是吧。
那這樣看:
array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
想到了什么?咱們當(dāng)做一個(gè)平面直角坐標(biāo)系。
相當(dāng)于arr1[x,y],x相當(dāng)于行數(shù),y相當(dāng)于列數(shù)(必須聲明,圖中x和y標(biāo)反了,但不影響理解)。
多維數(shù)組
先說(shuō)明下reshape()更改形狀:
np.reshape(a,newshape,order='C')
a:array_like以一個(gè)數(shù)組為參數(shù)。
newshape:intortupleofints。整數(shù)或者元組
順便說(shuō)明下,np.reshape()不更改原數(shù)組形狀(會(huì)生成一個(gè)副本)。
arr1 = np.arange(12) arr2 = arr1.reshape(2,2,3) #將arr1變?yōu)?×2×3數(shù)組 arr2 Out[9]: array([[[ 0, 1, 2], [ 3, 4, 5]], [[ 6, 7, 8], [ 9, 10, 11]]])
其實(shí)多維數(shù)組就相當(dāng)于:
row * col * 列中列
那么:
arr2[0] Out[10]: array([[0, 1, 2], [3, 4, 5]]) arr2[1] Out[11]: array([[ 6, 7, 8], [ 9, 10, 11]]) arr2[0,1] Out[12]: array([3, 4, 5]) arr2[0] = 23 #賦值 arr2 Out[15]: array([[[23, 23, 23], [23, 23, 23]], [[ 6, 7, 8], [ 9, 10, 11]]])
切片索引
那么這樣也就很容易的就可以理解下面這種索引了。
切片索引把每一行每一列當(dāng)做一個(gè)列表就可以很容易的理解。
返回的都是數(shù)組。
再?gòu)?fù)雜一點(diǎn):
我們想要獲得下面這個(gè)數(shù)組第一行的第2,3個(gè)數(shù)值。
arr1 = np.arange(36)#創(chuàng)建一個(gè)一維數(shù)組。 arr2 = arr1.reshape(6,6) #更改數(shù)組形狀。 Out[20]: 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]])
為了得到第2,3個(gè)數(shù),我們可以:
arr2[0,2:4] Out[29]: array([2, 3])
可以發(fā)現(xiàn)ndarray的切片其實(shí)與列表的切片是差不太多的。
我們還可以這樣:
arr2[1] #取得第2行 Out[37]: array([ 6, 7, 8, 9, 10, 11]) arr2[:,3] #取得第3列, 只有:代表選取整列(也就是整個(gè)軸) Out[38]: array([ 3, 9, 15, 21, 27, 33]) arr2[1:4,2:4] # 取得一個(gè)二維數(shù)組 Out[40]: array([[ 8, 9], [14, 15], [20, 21]]) arr2[::2,::2] #設(shè)置步長(zhǎng)為2 Out[41]: array([[ 0, 2, 4], [12, 14, 16], [24, 26, 28]]) arr3 = arr2.reshape(4,3,3) arr3[2:,:1] = 22 #對(duì)切片表達(dá)式賦值 arr3 Out[25]: array([[ 0, 1, 2, 3, 4, 5], [ 6, 7, 8, 9, 10, 11], [22, 13, 14, 15, 16, 17], [22, 19, 20, 21, 22, 23], [22, 25, 26, 27, 28, 29],
布爾型索引
arr3 = (np.arange(36)).reshape(6,6)#生成6*6的數(shù)組 arr3 Out[35]: 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]]) x = np.array([0, 1, 2, 1, 4, 5]) x == 1#通過(guò)比較運(yùn)算得到一個(gè)布爾數(shù)組 Out[42]: array([False, True, False, True, False, False], dtype=bool) arr3[x == 1] #布爾索引 Out[43]: array([[ 6, 7, 8, 9, 10, 11], [18, 19, 20, 21, 22, 23]])
從結(jié)果上看,布爾索引取出了布爾值為True的行。
布爾型數(shù)組的長(zhǎng)度和索引的數(shù)組的行數(shù)(軸長(zhǎng)度)必須一致。
布爾型數(shù)組可與切片,整數(shù)(整數(shù)序列)一起使用。
arr3[x == 1,2:]#切片 Out[44]: array([[ 8, 9, 10, 11], [20, 21, 22, 23]]) arr3[x == 1,-3:]#切片 Out[47]: array([[ 9, 10, 11], [21, 22, 23]]) arr3[x == 1,3]#整數(shù) Out[48]: array([ 9, 21])
!= 不等于符號(hào)。
~ 負(fù)號(hào)可以對(duì)條件進(jìn)行否定。logical_not()函數(shù)也可以。
x != 1 Out[49]: array([ True, False, True, False, True, True], dtype=bool) arr3[~(x == 1)] #實(shí)際類似于取反 Out[51]: array([[ 0, 1, 2, 3, 4, 5], [12, 13, 14, 15, 16, 17], [24, 25, 26, 27, 28, 29], [30, 31, 32, 33, 34, 35]]) arr3[np.logical_not(x == 1)] #作用于 ~ 相同 Out[53]: array([[ 0, 1, 2, 3, 4, 5], [12, 13, 14, 15, 16, 17], [24, 25, 26, 27, 28, 29], [30, 31, 32, 33, 34, 35]])
組合多個(gè)條件,使用布爾運(yùn)算符&(和),|(或)
(x == 1 ) & (x == 4)#和 Out[67]: array([False, False, False, False, False, False], dtype=bool) (x==1)|(x==4)#或 Out[68]: array([False, True, False, True, True, False], dtype=bool) arr3[(x==1)|(x==4)]#布爾索引 Out[71]: array([[ 6, 7, 8, 9, 10, 11], [18, 19, 20, 21, 22, 23], [24, 25, 26, 27, 28, 29]])
通過(guò)以上的代碼實(shí)驗(yàn),我們也可以發(fā)現(xiàn),布爾索引不更改原數(shù)組,創(chuàng)建的都是原數(shù)組的副本。
那這個(gè)東西能做什么呢?其他索引能做的,他基本也都可以。
比如有這樣一個(gè)數(shù)組:
arr5 = np.random.randn(4,4)#randn返回一個(gè)服從標(biāo)準(zhǔn)正態(tài)分布的數(shù)組。 arr5 Out[77]: array([[-0.64670829, 1.53428435, 0.20585387, 0.42680995], [-0.63504514, 0.54542881, -0.82163028, -0.89835051], [-0.66770299, 0.22617913, 0.16358189, -0.75074314], [-0.25439447, -0.96135628, -0.10552532, -1.06962358]])
我們要將arr5大于0的數(shù)值變?yōu)?0:
arr5[arr5 > 0] = 10 arr5 Out[80]: array([[ -0.64670829, 10. , 10. , 10. ], [ -0.63504514, 10. , -0.82163028, -0.89835051], [ -0.66770299, 10. , 10. , -0.75074314],
當(dāng)然,布爾索引也可以結(jié)合上面的運(yùn)算符來(lái)進(jìn)行操作。
花式索引
花式索引(Fancy indexing),指的是利用整數(shù)數(shù)組進(jìn)行索引。
第一次看到這個(gè)解釋,我是一臉懵的。
試驗(yàn)后,我才理解。
arr6 = np.empty((8,4))# 創(chuàng)建新數(shù)組,只分配內(nèi)存空間,不填充值 for i in range(8):#給每一行賦值 arr6[i] = i arr6 Out[5]: 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.]]) arr6[[2,6,1,7]] #花式索引 Out[14]: array([[ 2., 2., 2., 2.], [ 6., 6., 6., 6.], [ 1., 1., 1., 1.], [ 7., 7., 7., 7.]])
我們可以看到花式索引的結(jié)果,以一個(gè)特定的順序排列。
而這個(gè)順序,就是我們所傳入的整數(shù)列表或者ndarray。
這也為我們以特定的順序來(lái)選取數(shù)組子集,提供了思路。
arr6[2] Out[15]: array([ 2., 2., 2., 2.]) arr6[6] Out[17]: array([ 6., 6., 6., 6.]) arr6[1] Out[18]: array([ 1., 1., 1., 1.])
可以看到,花式索引的結(jié)果與普通索引是一致的。只不過(guò),花式索引簡(jiǎn)化了索引過(guò)程,而且還實(shí)現(xiàn)了按一定的順序排列。
還可以使用負(fù)數(shù)(其實(shí)類似于列表)進(jìn)行索引。
arr6[[-2,-6,-1]] Out[21]: array([[ 6., 6., 6., 6.], [ 2., 2., 2., 2.], [ 7., 7., 7., 7.]])
一次傳入多個(gè)索引數(shù)組,會(huì)返回一個(gè)一維數(shù)組,其中的元素對(duì)應(yīng)各個(gè)索引元組。
有點(diǎn)懵。
arr7 = np.arange(35).reshape(5,7)#生成一個(gè)5*7的數(shù)組 arr7 Out[24]: 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]]) arr7[[1,3,2,4],[2,0,6,5]] Out[27]: array([ 9, 21, 20, 33])
經(jīng)過(guò)對(duì)比可以發(fā)現(xiàn),返回的一維數(shù)組中的元素,分別對(duì)應(yīng)(1,2)、(3,0)....
這一樣一下子就清晰了,我們傳入來(lái)兩個(gè)索引數(shù)組,相當(dāng)于傳入了一組平面坐標(biāo),從而進(jìn)行了定位。
此處,照我這樣理解的話,那么一個(gè)N維數(shù)組,我傳入N個(gè)索引數(shù)組的話,是不是相當(dāng)于我傳入了一個(gè)N維坐標(biāo)。
我試驗(yàn)了下三維,是這樣的,但是以后的不知道了。誰(shuí)知道求告訴。
ar = np.arange(27).reshape(3,3,3) ar Out[31]: 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]]]) ar[[1,2],[0,1],[2,2]] Out[32]: array([11, 23])
那么應(yīng)該如何得到一個(gè)矩形區(qū)域呢。可以這樣做:
arr7[[1,3,2,4]][:,[2,0,6,5]] Out[33]: array([[ 9, 7, 13, 12], [23, 21, 27, 26], [16, 14, 20, 19], [30, 28, 34, 33]])
必須明白,arr7[2][3]等價(jià)于arr7[2,3]
那么上面這種得到矩形區(qū)域的方法,就相當(dāng)于行與列去了交集。
此外還可用np.ix_函數(shù),它的作用與上面的方法類似,只不過(guò)是將兩個(gè)一維的數(shù)組轉(zhuǎn)換為了一個(gè)可以選擇矩形區(qū)域的索引器。
arr7[np.ix_([1,3,2,4],[2,0,6,5])] Out[34]: array([[ 9, 7, 13, 12], [23, 21, 27, 26], [16, 14, 20, 19], [30, 28, 34, 33]])
通過(guò),這些試驗(yàn),還可發(fā)現(xiàn),花式索引將數(shù)據(jù)復(fù)制到了一個(gè)新的數(shù)組中。
總結(jié)
以上就是本文關(guān)于numpy中索引和切片詳解的全部?jī)?nèi)容,希望對(duì)大家有所幫助。感興趣的朋友可以繼續(xù)參閱本站:
利用numpy實(shí)現(xiàn)一、二維數(shù)組的拼接簡(jiǎn)單代碼示例
如有不足之處,歡迎留言指出。感謝朋友們對(duì)本站的支持!
相關(guān)文章
python目標(biāo)檢測(cè)給圖畫框,bbox畫到圖上并保存案例
這篇文章主要介紹了python目標(biāo)檢測(cè)給圖畫框,bbox畫到圖上并保存案例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-03-03用python實(shí)現(xiàn)k近鄰算法的示例代碼
這篇文章主要介紹了用python實(shí)現(xiàn)k近鄰算法的示例代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-09-09基于Python數(shù)據(jù)可視化利器Matplotlib,繪圖入門篇,Pyplot詳解
下面小編就為大家?guī)?lái)一篇基于Python數(shù)據(jù)可視化利器Matplotlib,繪圖入門篇,Pyplot詳解。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-10-10在DigitalOcean的服務(wù)器上部署flaskblog應(yīng)用
這篇文章主要介紹了在DigitalOcean的服務(wù)器上部署flaskblog的方法,flaskblog是用Python的Flask開(kāi)發(fā)的一個(gè)博客程序,而DigitalOcean則是大受歡迎的SSD主機(jī)提供商,需要的朋友可以參考下2015-12-12Python+SQLAlchemy輕松實(shí)現(xiàn)管理數(shù)據(jù)庫(kù)
QLAlchemy是一個(gè)強(qiáng)大的ORM(對(duì)象關(guān)系映射)庫(kù),它允許您通過(guò)Python代碼與關(guān)系型數(shù)據(jù)庫(kù)進(jìn)行交互,本文我們將學(xué)習(xí)如何使用Python和SQLAlchemy庫(kù)來(lái)輕松管理數(shù)據(jù)庫(kù),需要的可以參考下2023-05-05tensorflow保持每次訓(xùn)練結(jié)果一致的簡(jiǎn)單實(shí)現(xiàn)
今天小編就為大家分享一篇tensorflow保持每次訓(xùn)練結(jié)果一致的實(shí)現(xiàn),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-02-02Python使用urllib2模塊抓取HTML頁(yè)面資源的實(shí)例分享
這篇文章主要介紹了Python使用urllib2模塊抓取HTML頁(yè)面資源的實(shí)例分享,將要抓取的頁(yè)面地址寫在單獨(dú)的規(guī)則列表中方便組織和重復(fù)使用,需要的朋友可以參考下2016-05-05ubuntu16.04升級(jí)Python3.5到Python3.7的方法步驟
這篇文章主要介紹了ubuntu16.04升級(jí)Python3.5到Python3.7的方法步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-08-08python項(xiàng)目導(dǎo)入open3d后報(bào)錯(cuò)ImportError:DLL load failed:找不到
這篇文章主要介紹了python項(xiàng)目導(dǎo)入open3d后報(bào)錯(cuò)ImportError:DLL load failed:找不到指定的模塊問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-08-08