numpy 學習彙總25
阿新 • • 發佈:2019-02-11
花式索引 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 等同。 ==================================================================