1. 程式人生 > >numpy 學習彙總25

numpy 學習彙總25

花式索引  2018/11/11  2018/11/24
    
==================================================================
    說明
    #  1)NumPy陣列可用切片進行索引
    #  2)可用布林或整數陣列(掩碼)進行索引.這種方法稱為花式索引.
    # .3)花式索引跟切片不一樣,它建立副本而不是檢視。
    #  4)  新陣列與條件陣列形狀相同
    #  5)索引陣列中索引元素應<行m   a.shape(m,n)
   用法:a[ [ bool or  int]]
==================================================================
    
1.使用布林掩碼
    
例項1:
    
a1=np.arange(10, 20)                    # array([10, 11, 12, 13, 14, 15, 16, 17, 18, 19])
a2=np.arange(10,22).reshape(3,4)#array([[10, 11, 12, 13],[14, 15, 16, 17],[18, 19, 20, 21]])
    
mask = (a1 % 2 == 0) # array([ True, False,  True, False,  True, False,  True, False,  True, False])
# b1= a1[mask]          # 等價a[a%2==0]
b1=a1[a1 %2 ==0]     # array([10, 12, 14, 16, 18])
b2=a2[a2%2==0]       # array([10, 12, 14, 16, 18, 20])
    
這個屬性在賦值時非常有用:
a1[mask] = 0              # 所有偶數變成0
a                                #array([ 0, 11,  0, 13,  0, 15,  0, 17,  0, 19])
    
例項2:
#第二種布林索引方法近似整數索引;對陣列每個維度給一個一維布林陣列來選擇我們想要的切片。
    
a = np.arange(12).reshape(3,4)
b1 = np.array([False,True,True])             # first dim selection
b2 = np.array([True,False,True,False])   # second dim selection
    
a[b1,:]                         # selecting rows
                                   # array([[ 4,  5,  6,  7],[ 8,  9, 10, 11]])
a[b1]                           # same thing
                                   # array([[ 4,  5,  6,  7],[ 8,  9, 10, 11]])
    
a[:,b2]                         # selecting columns
                                   # array([[ 0,  2],[ 4,  6],[ 8, 10]])
    
a[b1,b2]                      # array([ 4, 10])
    
注意:
# 一維陣列的長度必須和你想要切片的維度或軸的長度一致,
# 在例子中,b1是一個秩為1長度為三的陣列(a的行數),b2(長度為4)與a的第二秩(列)相一致。
    

===================================================================
2.整數索引
    
a1=np.arange(10, 20)                    # array([10, 11, 12, 13, 14, 15, 16, 17, 18, 19])
a2=np.arange(10,22).reshape(3,4)#array([[10, 11, 12, 13],[14, 15, 16, 17],[18, 19, 20, 21]])
    
# 2.1.使用整數陣列-     #索引元素應<=行m   a.shape(m,n)
b1=a1[[4,3, 2, 1]]      # array([14, 13, 12, 11])
b2=a2[[2, 1,0]]          #array([[18, 19, 20, 21],[14, 15, 16, 17],[10, 11, 12, 13]])
    
# 2.2.傳入多個索引陣列:1D 容易出錯
idx1 = np.array([[3, 4], [9, 7]])        #索引元素應<10
a1[idx1]                                          #array([[13, 14],[19, 17]])
# a1[[3, 4], [9, 7]]/a1[[[3, 4], [9, 7]]]#錯誤用法
    
# 2.3.傳入多個索引陣列:2D 容易出錯
# idx2 = np.array([[1, 2], [2, 3]]) #
# a2[idx2]                                  #錯誤用法
a2[[1,2],[2,3]]#array([16, 21])   #索引元素應前面<3,後面<4 終選元素(1,2),(2,3)
a2[[1,2]]        #array([[14, 15, 16, 17],[18, 19, 20, 21]])
    
====================================================================
3.ix_將兩個一維陣列轉換為一個用於選取方形區域的索引器:
    ix_ 函式可以為了獲得 多元組 的結果而用來結合不同向量
    
# 例項1:1D
    
a1=np.arange(10, 20)                    # array([10, 11, 12, 13, 14, 15, 16, 17, 18, 19])
a2=np.arange(10,22).reshape(3,4)#array([[10, 11, 12, 13],[14, 15, 16, 17],[18, 19, 20, 21]])
    
np.ix_([0, 1, 2],[1, 2, 3])        #(array([[0],[1],[2]]), array([[1, 2, 3]]))# 第1,2,3行,第2,3,4列區域
a1[ix1[0]]#array([[10], [11], [12]])
a1[ix1[1]]#array([[11, 12, 13]])
    
#例項2:2D
a2[ix1]                    #array([[11, 12, 13], [15, 16, 17],[19, 20, 21]])# 第1,2,3行,第2,3,4列區域
a2[[0,1,2]][:,[1,2,3]]# 等價於上面
a2[[0,1,2]][[1,2]]     #array([[14, 15, 16, 17],[18, 19, 20, 21]]) 先選取前3行,然後在從結果總選擇第2,3行
    
# 例項3:如果你想要用所有向量a、b和c元素組成的三元組來計算 a+b*c :
a = array([2,3,4,5])
b = array([8,5,4])
c = array([5,4,6,8,3])
ax,bx,cx = ix_(a,b,c)
ax
# array([[[2]],
#        [[3]],
#        [[4]],
#        [[5]]])
bx
# array([[[8],
#         [5],
#         [4]]])
cx
# array([[[5, 4, 6, 8, 3]]])
ax.shape, bx.shape, cx.shape # ((4, 1, 1), (1, 3, 1), (1, 1, 5))
result = ax+bx*cx
result
# array([[[42, 34, 50, 66, 26],
#             [27, 22, 32, 42, 17],
#             [22, 18, 26, 34, 14]],
#            [[43, 35, 51, 67, 27],
#             [28, 23, 33, 43, 18],
#             [23, 19, 27, 35, 15]],
#            [[44, 36, 52, 68, 28],
#             [29, 24, 34, 44, 19],
#             [24, 20, 28, 36, 16]],
#            [[45, 37, 53, 69, 29],
#             [30, 25, 35, 45, 20],
#             [25, 21, 29, 37, 17]]])
result[3,2,4]  # 17
a[3]+b[2]*c[4]# 17
    
# 例項4:你也可以實行如下簡化:
def ufunc_reduce(ufct, *vectors):
    vs = ix_(*vectors)
    r = ufct.identity
    for v in vs:
        r = ufct(r,v)
    return r
    
# 然後這樣使用它:
ufunc_reduce(add,a,b,c)
    
# array([[[15, 14, 16, 18, 13],
#             [12, 11, 13, 15, 10],
#             [11, 10, 12, 14,  9]],
#            [[16, 15, 17, 19, 14],
#             [13, 12, 14, 16, 11],
#             [12, 11, 13, 15, 10]],
#            [[17, 16, 18, 20, 15],
#             [14, 13, 15, 17, 12],
#             [13, 12, 14, 16, 11]],
#            [[18, 17, 19, 21, 16],
#             [15, 14, 16, 18, 13],
#             [14, 13, 15, 17, 12]]])
    
# 這個reduce與ufunc.reduce(比如說add.reduce)相比的優勢在於它利用了廣播法則,
# 避免了建立一個輸出大小乘以向量個數的引數陣列。:
    
=====================================================================
    
4.多維的索引,每一維的索引陣列必須有相同的形狀。
    
a = np.arange(12).reshape(3,4)
                # array([[ 0,  1,  2,  3],
                #            [ 4,  5,  6,  7],
                #            [ 8,  9, 10, 11]])
i = np.array( [[0,1], [1,2]] )       # indices for the first dim of a
j = np.array( [[2,1], [3,3]] )       # indices for the second dim
    
a[i,j]                                         # i and j must have equal shape
                # array([[ 2,  5],
                #           [ 7, 11]])
    
a[i,2]
                # array([[ 2,  6],
                #           [ 6, 10]])
    
a[:,j]
                # array([[[2, 1],
                #            [3, 3]],
                #
                #           [[6, 5],
                #            [7, 7]],
                #
                #           [[10, 9],
                #            [11, 11]]])
    
# 可把i和 j放到序列中:然後通過list索引
 l = [i,j]
a[l]              # equivalent to a[i,j]
                   # array([[ 2,  5],[ 7, 11]])
# 可把i和 j放到序列中:然後通過tuple索引
a[tuple(s)]  # same as a[i,j]
                  # array([[ 2,  5],[ 7, 11]])
注意:
不能把i 和j放在陣列中,因為這個陣列將被解釋成索引a的第一維
s = np.array( [i,j] )
a[s]          # not what we want
    
==================================================================
5.可以使用陣列索引作為目標來賦值:
a[[9, 7]] = -100
    
小心如果你想用Python的 += 結構,可能結果並非你所期望:
a = arange(5)
a[[0,0,2]]+=1
a # array([1, 1, 3, 3, 4])
    
# 即使0在索引列表中出現兩次,索引為0的元素僅僅增加一次。這是因為Python要求a+=1 和 a=a+1 等同。
==================================================================