numpy模塊之數組的切片索引

咱們先來看看一階數組的切片索引python

import numpy as np

arr = np.arange(10) 
print(arr) 
print(arr[5]) 
print(arr[5:8])  

[0 1 2 3 4 5 6 7 8 9] 
5 
[5 6 7]

注意:數組的切片獲得的是一個原始數組的一個視圖,即原始數據並無被複制而造成新的拷貝,視圖上的任何修改都會直接反應到原始數組之上,這和python內置列表是有很大區別數組

import numpy as np  

arr = np.arange(10) 
arr[5:8] = 999 
print(arr)  

[  0   1   2   3   4 999 999 999   8   9]
import numpy as np  

arr = np.arange(10) 
temp = arr[5:8] 
temp[1] = 888 
print(arr)  

[  0   1   2   3   4   5 888   7   8   9]

這樣作的緣由是,numpy的設計目的是處理大數據,避免數據的反覆複製有利於節省內存、提高性能。dom

若是執意要得到ndarray切片的一份副本而非視圖,則須要顯式的進行復制操做。函數

import numpy as np  

arr = np.arange(10) 
temp = arr[5:8].copy() 
temp[1] = 888 
print(arr)  

[0 1 2 3 4 5 6 7 8 9]

高維數組的索引

在一個二維數組中,顯而易見的是,各索引位置上的元素再也不是標量而是一維數組性能

import numpy as np  

arr2d = np.array([[1,2,3],[4,5,6],[7,8,9]]) 
print(arr2d[2]) 
print(arr2d[0,1]) 
print(arr2d[0][1])  

[7 8 9] 
2
2

更高階的數組大數據

import numpy as np  

arr3d = np.array([[[1,2,3],[4,5,6]],[[7,8,9],[10,11,12]]]) 
print(arr3d[0]) 
print(arr3d[1][0]) 
print(arr3d[0][0][1]) 

[[1 2 3]  [4 5 6]]  
[7 8 9]  
2
#咱們看其中,arr3d[1][0]:

#第一個索引「1」:把[[[1,2,3],[4,5,6]],[[7,8,9],[10,11,12]]]最外層的中括號去掉,
#[[1,2,3],[4,5,6]],[[7,8,9],[10,11,12]],獲得[[7,8,9],[10,11,12]],第二個索引「0」,再去掉一箇中括號[7,8,9],[10,11,12],獲得結果[7,8,9]

和前面描述的相似,ndarray利用索引返回的低維數組子集也是視圖而非拷貝,獲取拷貝也須要顯式的調用copy函數。標量和等維的數組均可以對數據進行賦值。spa

import numpy as np  

arr3d = np.array([[[1,2,3],[4,5,6]],[[7,8,9],[10,11,12]]]) 
arr3d[0] = 111  
print(arr3d)  

[[[111 111 111]   [111 111 111]]   
 [[  7   8   9]   [ 10  11  12]]]



import numpy as np  

arr3d = np.array([[[1,2,3],[4,5,6]],[[7,8,9],[10,11,12]]]) 
arr_cpy = arr3d[0].copy() 
arr3d[0] = 111  
print(arr3d) 

[[[111 111 111]   [111 111 111]]   
 [[  7   8   9]   [ 10  11  12]]]  

arr3d[0] = arr_cpy 
print(arr3d)  

[[[ 1  2  3]   [ 4  5  6]]   
 [[ 7  8  9]   [10 11 12]]]
import numpy as np  

arr2d = np.array([[1,2,3],[4,5,6],[7,8,9]]) 
print(arr2d[:2,1:])  

[[2 3]  [5 6]]
#同理,從左到右的切片索引,就是從外到內處理中括號的過程,
#第一個「:2」高維度的切片,是對高維進行切片,即選取第0行和第1行(左閉右開),獲得[[1,2,3],[4,5,6]]
#第二個「1:」則是在此基礎上對低維進行切片,即第一列到最後一列。最終獲得結果。

固然切片和整數索引是能夠混用的設計

import numpy as np  

arr2d = np.array([[1,2,3],[4,5,6],[7,8,9]]) 
print(arr2d[:2,1])  

[2 5]

經過切片獲取的也是原始數組的一個視圖,而且對切片表達式進行賦值操做,也是擴散到整個選區3d

import numpy as np  

arr2d = np.array([[1,2,3],[4,5,6],[7,8,9]]) 
arr2d[:2,1:] = 0 
print(arr2d)  

[[1 0 0]  [4 0 0]  [7 8 9]]

布爾索引code

咱們先看一個例子,對一個數組進行==斷定操做,會獲得一個等維度的bool數組

import numpy as np  

names = np.array(['tom','bob','bill','jack','tom']) 
arr_bool = names == 'tom' print(arr_bool)  

[ True False False False  True]

這個獲得的bool型數組能夠用於數組索引,前提是bool型數組的長度和被索引數組的高維維度一致

import numpy as np  

names = np.array(['tom','bob','bill','jack','tom']) 
arr_bool = names == 'tom'  
data = np.random.rand(5,3) 
print(data) 
print(data[arr_bool])  

[[ 0.09769032  0.97245502  0.1762949 ]  
 [ 0.59949381  0.46735516  0.64142579]  
 [ 0.45941574  0.06747531  0.55780872]  
 [ 0.29714417  0.78494754  0.5194105 ]  
 [ 0.78078671  0.96654222  0.27489762]]

[[ 0.09769032  0.97245502  0.1762949 ]  
 [ 0.78078671  0.96654222  0.27489762]]

固然,顯而易見的是,bool型數組也是能夠和切片、整數索引混用的

import numpy as np  

names = np.array(['tom','bob','bill','jack','tom']) 
data = np.random.rand(5,3) 
print(data) 
print(data[names == 'tom',1:])  

[[ 0.16915065  0.15038684  0.34028728]  
 [ 0.32732646  0.69241855  0.65203056]  
 [ 0.84402175  0.77184234  0.48730057]  
 [ 0.94376757  0.33876278  0.77287885]  
 [ 0.58535219  0.50321862  0.28196336]]  

[[ 0.15038684  0.34028728]  
 [ 0.50321862  0.28196336]]

經過bool型索引選取數組中的數據,將老是建立數據的副本,而非視圖

同時能夠利用布爾型數組進行條件賦值,這也是會常常用到的

import numpy as np  

names = np.array(['tom','bob','bill','jack','tom']) 
data = np.random.rand(5,3) 
print(data) 
data[data<0.5]=0 
print(data)  

[[ 0.11395235  0.30461958  0.02896975]  
 [ 0.54829738  0.25386957  0.71327458]  
 [ 0.95840718  0.01013043  0.75231583]  
 [ 0.1600976   0.09872024  0.96804632]  
 [ 0.16516135  0.44308404  0.90036341]]  

[[ 0.          0.          0.        ]  
 [ 0.54829738  0.          0.71327458]  
 [ 0.95840718  0.          0.75231583]  
 [ 0.          0.          0.96804632]  
 [ 0.          0.          0.90036341]]

也能夠利用一維bool數組進行整行、整列的賦值

import numpy as np  

names = np.array(['tom','bob','bill','jack','tom']) 
data = np.random.rand(5,3) 
print(data) 
data[names == 'tom']=0 
print(data)  

[[ 0.45025316  0.63122953  0.92612377]  
 [ 0.02918047  0.72361626  0.50190505]  
 [ 0.97611338  0.92807698  0.60883423]  
 [ 0.40124052  0.81103418  0.05447573]  
 [ 0.07352045  0.16173038  0.28114157]]  

[[ 0.          0.          0.        ]  
 [ 0.02918047  0.72361626  0.50190505]  
 [ 0.97611338  0.92807698  0.60883423]  
 [ 0.40124052  0.81103418  0.05447573]  
 [ 0.          0.          0.        ]]

關於多維數組的索引,咱們最後看一種用法,利用整數數組進行索引:

按照整數數組中的索引值,來依次選取對應行

import numpy as np  

arr = np.empty((8,4)) 
for i in range(8):     
    arr[i] = i  
print(arr) 
print(arr[[4,3,0,6]])  

[[ 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.]] 

[[ 4.  4.  4.  4.]  
 [ 3.  3.  3.  3.]  
 [ 0.  0.  0.  0.]  
 [ 6.  6.  6.  6.]]

在此基礎上,再選取對應列,也是不難的

第一種狀況是,針對每一行選取特定的列

import numpy as np

arr = np.arange(32).reshape(8,4)
print(arr)
print(arr[[1,5,7,2],[0,3,1,2]]) 

[[ 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]]

[ 4 23 29 10]

能夠看出,是在選取的特定四行後,再在每一行中挑選出指定的值,最後結果就是四個數

第二種使用場景是,在按照指定順序選取行後,再按指定順序選取整列

import numpy as np  

arr = np.arange(32).reshape(8,4) 
print(arr) 
print(arr[[4,3,0,6]][:,[0,3,1,2]])  
[[ 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]]  

[[16 19 17 18]  
 [12 15 13 14]  
 [ 0  3  1  2]  
 [24 27 25 26]]
相關文章
相關標籤/搜索