前幾篇博文我寫了數組創建和數據運算,現在我們就來看一下數組對象的操作方法。使用索引和切片的方法選擇元素,還有如何數組的迭代方法。
一、索引機制
1.一維數組
In [1]: a = np.arange(10,16) In [2]: a Out[2]: array([10, 11, 12, 13, 14, 15]) #使用正數作為索引 In [3]: a[3] Out[3]: 13 #還可以使用負數作為索引 In [4]: a[-4] Out[4]: 12 #方括號中傳入多數索引值,可同時選擇多個元素
In [6]: a[[0,3,4]]
Out[6]: array([10, 13, 14])
2.二維數組
二維數組也被稱為矩陣,是由行和列組成的。axes為2,用0軸表示行,用1表示列。[行索引,列索引]
In [14]: A Out[14]: array([[10, 11, 12], [13, 14, 15], [16, 17, 18]])
#取出第三行第二列的元素 In [15]: A[2,1] Out[15]: 17
#可以使用方括號取出多個元素 In [17]: A[[[2,1],[1,2]]] Out[17]: array([17, 15])
二、切片操作:抽取部分數組元素生成新數組
1.一維數組切片操作
In [26]: a = np.arange(10,20) In [27]: a[2:7] Out[27]: array([12, 13, 14, 15, 16]) In [28]: a[5:8] Out[28]: array([15, 16, 17]) #設置步長 In [30]: a[2:8:2] Out[30]: array([12, 14, 16]) #省去第一個數,則認為是從0(第一個元素)開始的 In [31]: a[:8:2] Out[31]: array([10, 12, 14, 16]) #省去第二個數,則認為是取最大索引值 In [32]: a[5::2] Out[32]: array([15, 17, 19]) #省去第三個數,則認為步長為1 In [33]: a[5:8:] Out[33]: array([15, 16, 17]) #省去前兩個數,則認為是選取步長為X的所有元素 In [34]: a[::2] Out[34]: array([10, 12, 14, 16, 18])
2.二維數組切片操作
二維數組的切片操作與一維數組差不多,只不過讀了一個軸,那么方括號里面就要有兩個值(使用逗號隔開),可以把逗號的左邊和右邊當做是一個一位數組,比如:A[0:2,0:2]
In [1]: A = np.arange(10,19).reshape(3,3) In [2]: A Out[2]: array([[10, 11, 12], [13, 14, 15], [16, 17, 18]]) #第一個索引使用了冒號,則代表取所有行,第二個索引是0,則代表選取第一列。即第一列的所有元素 In [3]: A[:,0] Out[3]: array([10, 13, 16]) In [4]: A[0,:] Out[4]: array([10, 11, 12])
#行選取了0:2,即第一第二行(冒號的右邊表示結束值,不在選取范圍之內),列也是一樣的道理 In [5]: A[0:2,0:2] Out[5]: array([[10, 11], [13, 14]])
#如果要選取不連續的元素,可以將這些索引放入一個數組內。下面就是選取了第一行和第三行,第一和第二列的元素 In [6]: A[[0,2],0:2] Out[6]: array([[10, 11], [16, 17]])
3.注意:python對列表的切片得到的是數組的副本,而numpy數組切片得到的是指向相同緩沖區的視圖。原數據改變,切片得到的數組也會隨之改變。
三、數組的迭代
當我們用函數處理行、列或者單個元素時,會需要到數組的遍歷。
1.一維數組,使用for..in循環即可
In [7]: a = np.arange(0,11) In [8]: a Out[8]: array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) In [9]: for i in a: ...: print i 0 1 2 3 4 5 6 7 8 9 10
2.二維數組
也可以使用for循環,嵌套使用即可。但是實際上,你會發現它總是按照第一條軸對二維數組進行掃描。
In [10]: for row in A: ...: print row ...: [10 11 12] [13 14 15] [16 17 18]
如果想遍歷數組的每一個元素。可以循環遍歷A.flat
In [13]: for i in A.flat: ...: print i 10 11 12 13 14 15 16 17 18
用for循環就顯得沒那么優雅了,numpy提供了一個更優雅的遍歷方法:apply_along_axis(func,axis,arr),這個函數可以使用聚合函數對每一列或行進行處理,並返回一個數值作為結果。
這個函數接收三個參數,第一個是聚合函數,第二個是對應哪條軸(axis=0按列操作,axis=1按行操作),第三個是要處理的數組
In [14]: A Out[14]: array([[10, 11, 12], [13, 14, 15], [16, 17, 18]]) #axis為1,按行進行操作,則輸出每行最大的值 In [15]: np.apply_along_axis(np.max,axis=1,arr=A) Out[15]: array([12, 15, 18]) #輸出每行的平均值 In [16]: np.apply_along_axis(np.mean,axis=1,arr=A) Out[16]: array([ 11., 14., 17.])
其中,第一個參數可以傳遞自己寫的函數
In [17]: def foo(x): ...: return x/2 In [18]: np.apply_along_axis(foo,axis=1,arr=A) Out[18]: array([[5, 5, 6], [6, 7, 7], [8, 8, 9]])
四、使用條件表達式和布爾運算符選擇性地抽取元素
In [20]: B = np.random.random((3,3)) In [21]: B Out[21]: array([[ 0.11802695, 0.66445966, 0.06007488], [ 0.31908974, 0.35200425, 0.64225707], [ 0.60802331, 0.93322485, 0.28177795]]) #由條件表達式得到一個布爾數組 In [22]: B < 0.5 Out[22]: array([[ True, False, True], [ True, True, False], [False, False, True]], dtype=bool) #將條件表達式放在方括號中,可以抽取滿足表達式的數組,組成一個新數組。 In [23]: B[B<0.5] Out[23]: array([ 0.11802695, 0.06007488, 0.31908974, 0.35200425, 0.28177795])
五、總結
了解的數組的索引機制,對數組的切片操作,以及遍歷。