各位客官姥爺好,歡迎回來。上節(jié)我們了解了numpy數(shù)組的屬性以及淺拷貝和深拷貝,這節(jié)我們來看看數(shù)組的其他用法。 01 改變數(shù)組的維度 0. 聲明一個numpy的數(shù)組 x = np.random.randint(1,10,(3,4)) x array([[6, 3, 5, 8], [7, 9, 9, 2], [7, 8, 8, 9]]) 1. 改為一維數(shù)組 這里有兩種方法: 1)flatten( order='C' )方法 y = x.flatten() print(y) y[0] = 1 print(y) print(x) [6 3 5 8 7 9 9 2 7 8 8 9] [1 3 5 8 7 9 9 2 7 8 8 9] [[6 3 5 8] [7 9 9 2] [7 8 8 9]] 2)ravel([order])方法 y = x.ravel() print(y) y[0] = 1 print(y) print(x) [6 3 5 8 7 9 9 2 7 8 8 9] [1 3 5 8 7 9 9 2 7 8 8 9] [[1 3 5 8] [7 9 9 2] [7 8 8 9]] 這里特別注意,當(dāng)使用ravel時,修改新對象的值,源對象的值也會改變。 2. 改為其他維數(shù)的數(shù)組 這里同樣有兩種方法: 1)reshape( shape , order='C' ) 方法 x = np.random.randint(1,10,(2,6)) print(x) m = x.reshape((3,4)) print(m) m[0,1] = 88 print(m) print(x) [[2 6 9 5 4 1] [4 6 1 3 4 9]] [[2 6 9 5] [4 1 4 6] [1 3 4 9]] [[ 2 88 9 5] [ 4 1 4 6] [ 1 3 4 9]] [[ 2 88 9 5 4 1] [ 4 6 1 3 4 9]] 同樣,需要注意:更改新對象的元素,源對象的也會改變。 2)resize( new_shape , refcheck=True )方法 resize方法直接在源數(shù)組上更改。 x = np.random.randint(1,10,(2,6)) print(x) #在這里賦值給y,y直接返回None。 y = x.resize((3,4)) print(x) print(y) [[8 3 1 1 5 6] [6 7 9 5 2 5]] [[8 3 1 1] [5 6 6 7] [9 5 2 5]] None 02 數(shù)組索引相關(guān) 1.根據(jù)索引取值 take(indices, axis=None, out=None, mode='raise')方法 x = np.random.randint(1,10,(2,6)) print(x) y = x.take([[1,2],[7,8]]) print(y) [[4 7 9 1 9 6] [1 7 6 4 2 9]] [[7 9] [7 6]] 如果不使用axis參數(shù)的話,默認(rèn)把數(shù)組展開成一維。 x = np.random.randint(1,10,(2,6)) print(x) y = x.take([[1,2],[4,5]], axis=1) print(y) [[3 2 2 3 2 5] [3 6 6 6 3 6]] [[[2 2] [2 5]] [[6 6] [3 6]]] x = np.random.randint(1,10,(2,6)) print(x) y = x.take([[1,2],[4,5]], axis=0) print(y) 更改axis=0,直接報錯超出范圍 IndexError: index 2 is out of bounds for size 2 可修改mode參數(shù)來避免報錯,有三種可選參數(shù):{'raise', 'wrap', 'clip'}。 --raise表示拋出異常(默認(rèn)) --wrap表示索引超出范圍對數(shù)據(jù)進(jìn)行環(huán)繞,環(huán)繞也就是重復(fù)使用,一輪用完,第二輪接著上。 x = np.random.randint(1,10,(5,6)) print(x) y = x.take([[1,2],[4,5]], axis=0,mode='wrap') print(y) [[4 4 9 6 6 7] [1 8 6 2 6 7] [7 9 8 6 4 3] [4 3 6 5 2 6] [9 4 6 9 5 2]] [[[1 8 6 2 6 7] [7 9 8 6 4 3]] [[9 4 6 9 5 2] [4 4 9 6 6 7]]] --clip:表示超出下標(biāo)的部分,全部用最后一個。 x = np.random.randint(1,10,(5,6)) print(x) y = x.take([[1,2],[4,5]], axis=0,mode='clip') print(y) [[8 9 2 3 2 2] [8 6 1 5 2 2] [7 7 1 3 4 8] [3 5 1 7 3 5] [8 4 1 6 5 1]] [[[8 6 1 5 2 2] [7 7 1 3 4 8]] [[8 4 1 6 5 1] [8 4 1 6 5 1]]] 2.根據(jù)索引替換值 put(indices, values, mode='raise')方法 x = np.random.randint(1,10,(2,6)) print(x) y = x.put([[1,2],[3,4]],-5,mode='clip') print(x) print(y) [[3 4 4 5 2 7] [3 6 5 2 6 5]] [[ 3 -5 -5 -5 -5 7] [ 3 6 5 2 6 5]] None 需要特別留意的是:這里是直接在源對象上更改,賦值的話返回的結(jié)果會是None。 要說起來從源對象上直接更改,這里也可以使用切片用法。 x = np.random.randint(1,10,(2,6)) print(x) x[0,:3:1] = 0 print(x) x[0:4:1,1] = 10 print(x) [[9 9 4 3 1 8] [5 7 1 6 4 4]] [[0 0 0 3 1 8] [5 7 1 6 4 4]] [[ 0 10 0 3 1 8] [ 5 10 1 6 4 4]] 03 數(shù)組的排序 1. 對數(shù)組進(jìn)行排序 sort(axis=-1,kind=None,order=None)用法 axis默認(rèn)值是-1,表示沿最后一個軸排序。 kind有{'quicksort'、'mergesort'、'heapsort'、'stable'}四種可選排序算法:quicksort快排(默認(rèn)),mergesort歸并排序,heapsort堆排序,stable穩(wěn)定排序。 x = np.random.randint(1,10,(2,6)) print(x) y = x.sort(axis=1) print(x) print(y) [[2 2 2 8 1 1] [3 2 5 7 1 7]] [[1 1 2 2 2 8] [1 2 3 5 7 7]] None 可以看到這里同樣是直接更改源對象。如果不想直接更改源對象,有什么辦法嗎?我們接著往下看。 2. 返回排序的索引 argsort(axis=- 1, kind=None, order=None)方法 x = np.random.randint(1,10,(2,6)) print(x) y = x.argsort() print(y) [[1 2 9 4 6 1] [2 2 4 8 4 8]] [[0 5 1 3 4 2] [0 1 2 4 3 5]] 看到這里返回的索引,是不是對我們上面的提問有了些頭緒:我們前面剛好又講過take的用法(可以根據(jù)索引返回值)。思路有了,這就開干。 x = np.random.randint(1,10,(2,6)) print(x) y = x.argsort(axis = 1) print('******') print(y) z = x.take(y,axis = 1) print('******') print(z) [[3 9 1 9 7 3] [7 6 4 8 9 4]] ****** [[2 0 5 4 1 3] [2 5 1 0 3 4]] ****** [[[1 3 3 7 9 9] [1 3 9 3 9 7]] [[4 7 4 9 6 8] [4 4 6 7 8 9]]] 但結(jié)果有點(diǎn)出乎意料,相當(dāng)于源數(shù)組的每行都使用了索引一次。那有沒有按照軸返回數(shù)組的方法呢?還真有(首先,在這里需要感謝這些numpy的開發(fā)人員,滿足我們的各種需求),具體用法是: numpy.take_along_axis(arr, indices, axis) arr參數(shù)就是數(shù)組,indices就是索引,話不多說開干。 x = np.random.randint(1,10,(2,6)) print(x) y = x.argsort(axis = 1) print('******') print(y) z = np.take_along_axis(x,y,axis = 1) print('******') print(z) [[9 9 5 5 2 1] [8 7 3 2 1 7]] ****** [[5 4 2 3 0 1] [4 3 2 1 5 0]] ****** [[1 2 5 5 9 9] [1 2 3 7 7 8]] 結(jié)果正確,over! 3. 按某些序列進(jìn)行排序 np.lexsort(keys, axis=- 1)方法,注意ndarray沒有l(wèi)exsort方法。 這里的key加s,表示可以多個,以最后一個為第一排序依據(jù)。 x = np.array([1,2,2,3,4,6,6,7]) y = np.array([9,0,3,1,2,6,5,0]) np.lexsort((y,x)) 通過結(jié)果可以看出,對x進(jìn)行排序,如果x相同的部分,則以y為排序依據(jù)。 array([0, 1, 2, 3, 4, 6, 5, 7], dtype=int64) 4.搜索排序 searchsorted(v, side='left', sorter=None)方法 返回小于或等于v值的值的索引位置。 x = np.array([9,0,3,1,2,6,5,0]) x.searchsorted(3,side='right') 5 side中的right/left其實(shí)就相當(dāng)于開區(qū)間還是閉區(qū)間。 以上就是本次的分享,歡迎各位客官姥爺關(guān)注我,方便您第一次時間收到【干貨】! |
|
來自: 徐_清風(fēng) > 《待分類》