咱們先來看看一階數組的切片索引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]]