1. 程式人生 > >numpy高階函式操作之——select、choose

numpy高階函式操作之——select、choose

一、什麼是np.select()

顧名思義,這個函式用用來“ 根據某一些條件 ” 來篩選出 “某一些元素 ”的函式,比如我有一個數組,我如果用if-else語句去做,當然也可以,比如我們讓小於6的元素各自加上10,大於等於6的元素統統變為100,我們可以這麼做,程式碼如下:

a=np.array([1,2,3,4,5,6,7,8,9,10])
aaa=[]      #儲存篩選結果的列表
for i in a: #通過迴圈去完成
    if(i<6):
        i=i+10
    else:
        i=100
    aaa.append(i)

print(aaa)

執行結果為  [11, 12, 13, 14, 15, 100, 100, 100, 100, 100] 

但是這樣做的缺點就是效率太過於低下,因為這樣做就是使用迴圈,條件判斷去完成,select()函式就是專門針對這種情況提出來的。

1、select函式的定義

     def select(condlist, choicelist, default=0):

     condlist引數:操作資料所依據的條件

     choicelist引數:根據condlist條件,索要執行的操作

      返回值:返回的是一個“ 列表” 。

      注意上面的condlist和choicelist都必須是寫成“ 列表 ”的形式。

     要實現上面同樣的操作,這裡只需要一句話就可以完成

a=np.array([1,2,3,4,5,6,7,8,9,10])
condlist=[a<6]      #第一個引數,必須用【】括起來,列表形式
print(condlist)
choicelist=[a+10]   #第二個引數,必須用【】括起來,列表形式
print(choicelist)
aa=np.select(condlist,choicelist,default=100)
print(aa)

     程式執行的結果為:

[array([ True,  True,  True,  True,  True, False, False, False, False,False])]
[array([11, 12, 13, 14, 15, 16, 17, 18, 19, 20])]
[11 12 13 14 15  100  100  100  100  100]       #由此可見,依然得到的是上面的結果。

什麼意思呢?可以這樣理解,對於第一個引數condlist=[ a<6 ],我們將a<6看成是一個條件,只不過這個條件是針對array型別的a的,第二個引數choicelist所要執行的操作是依據condlist而言的,即這裡的  [a+10]裡面的a+10這個操作,和 [a<6]這個裡面的,a<6是對應關係的,即當第一條件裡的每個元素滿足條件的時候,即為True的時候,就執行相應的操作,如果為false,那麼久不執行,而對於不滿足的元素,則執行預設的值,即default。

2、select() 對於多條件、多操作的篩選和執行 

     比如針對一個數組,我們規定小於6的就加上10,介於10~15之間的就平方,大於20的就乘以10,其他的就預設變為100.

a=np.array([[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]])
condlist=[a<6,np.logical_and(a>10,a<16),a>20]  #引數一,定義三個限制條件
print(condlist)
choicelist=[a+10,a**2,a*10]                    #引數二,定義三個不同的操作
print(choicelist)
aa=np.select(condlist,choicelist)
print(aa)

print('=======================================')

執行結果為:

[[ 11  12  13  14  15]                   #第一行分別加上了10
 [  0   0   0   0   0]
 [121 144 169 196 225]              #第三行每個數分別進行了平方
 [  0   0   0   0   0]
 [210 220 230 240 250]]             #第五行每個數分別乘以10

3、select函式總結

引數一,condlist=【條件一,條件二,條件三,,,,】

引數二,choicelist=【操作一,操作二,操作三,,,,,】

只有每個條件中,對應為true的才會執行相對應的操作,最終所有條件都不滿足的元素,則執行預設值default。

二、np.choose()函式

choose()函式,顧名思義,也是通過某一些條件去“選擇”相關的元素,choose的操作會比自己使用for-if-else效率要高。

1、choose()函式的定義

def choose(a, choices, out=None, mode='raise'):

引數 a :它必須是一個 int 型的 陣列,並且 a 中的元素,必須是0~n-1之間的數,這裡的n表示的就是陣列choices陣列最外層的維度數。

choices:表示的是要操作的陣列,要注意的是choices的陣列的維度是一定要和a進行匹配的,如果匹配不了,會出現錯誤。

引數out:接收運算結果的陣列,它的維度一定要和 a 是一樣的,是可選引數。

引數mode:預設的是raise,表示的是a陣列中的元素不能超過 n ,她還有兩個可選值,

               clip:將 a 中的 元素 如果小於0,則將其變為0,如果大於n-1,則變為n-1

              wrap:將a中的值 value變為value mod n,即值除以n的餘數。

2、choose的應用

(1)當a和choices都是相同維數的時候——a為1維,choices為1維

result=np.array([0,0,0,0,0])
aa=np.choose([4,2,1,3,0],[11,22,33,44,55],out=result)  #當a,與choices的尾數相同的時候
print(aa)
print(result)  #result是out輸出的,這裡和aa的結果是一樣的

執行結果:

[55 33 22 44 11]
[55 33 22 44 11]          #二者的結果是一樣的,這個地方使用了out,mode引數使用的是預設值

總結:因為choices的 n 為5,所以 a 中的元素不能夠超過5 ,它代表的是 choices中的 索引index。11對應0,22對應1,33對應2,44對應3,55對應4.

(2)當a的維數比choices的維數多的時候——a為2維,choices為1維

bb=np.choose([[4,2,1,3,0],[3,4,2,0,1],[0,2,1,4,3]],[11,22,33,44,55])
print(bb)

執行結果為:

[[55 33 22 44 11]
 [44 55 33 11 22]
 [11 33 22 55 44]]    # a 中的每一個索引 都分別與choices 對應著的。

(3)當a的維數比choices的維數少的時候——a為1維,choices為2維

cc=np.choose([4,2,1,3,0],[[11,22,33,32,31],[44,55,66,65,64],[77,88,99,98,97],[111,222,333,332,331],[444,555,666,665,664]])
print(cc)

 執行結果為:

[444  88  66 332  31]   # 444 對應於 choices[4,0],88對應於 choices[2,1],66 對應於 choices[1,2],332 對應於 choices                                                [3,3],31 對應於 choices[0,4]

總結:由此可知,choices的最外層索引index依然是與a進行匹配的,但是內層索引是按照從0開始,0、1、2、3、4逐漸遞增的。鑑於此,choices的內層元素數量依然要與a的個數進行匹配才行,否則會報錯。

(4)當a的維數和choices的維數都是多維的時候——a為2維,choices為2維

dd=np.choose([[4,2,1,3,0],[3,4,2,0,1],[0,2,1,4,3]],[[11,22,33,32,31],[44,55,66,65,64],[77,88,99,98,97],[111,222,333,332,331],[444,555,666,665,664]])

print(dd)

執行結果為:

[[444  88  66 332  31]
 [111 555  99  32  64]
 [ 11  88  66 665 331]]    #運算過程同上面的 (3)是類似的

總結:從上面的幾個例子可以看出,choose最終的輸出結果是和 a 一樣的。a中的數值不能超過choices的索引值,但是沒有要求一定要a和choices維度相同。

3、choose的綜合應用

a=[[1,0,2],[2,1,0],[2,0,1]]
c1=[[1,2,3],[4,5,6],[7,8,9]]
c2=[[11,22,33],[44,55,66],[77,88,99]]
choices=[c1,100,c2]
result=np.choose(a,choices)
print(result)

執行結果為:

[[100   2  33]
 [ 44 100   6]
 [ 77   8 100]]    #原理同上

再例如:

a = [[1, 0, 1], [0, 1, 0], [1, 0, 1]]
choices = [-10, 10]
result=np.choose(a, choices)
print(result)

結果為:

      [[ 10, -10,  10],
       [-10,  10, -10],
       [ 10, -10,  10]]