NumPy快餐教程(2) – 多維陣列進階
上一講我們介紹了ndarray的形狀變化和生成方法,這一節我們繼續討論多維陣列的使用方法。
訪問元素
NumPy中使用[]方括號來訪問元素。如果是一維陣列,就用下標數字,例如a[1],如果是多維陣列,就在方括號中使用元組tuple,例如a[(2,3,4)]
例:
In [1]: import numpy as np
In [2]: a20 = np.linspace(1,100,27)
In [3]: a20
Out[3]:
array([ 1. , 4.80769231, 8.61538462, 12.42307692,
16.23076923, 20.03846154, 23.84615385, 27.65384615,
31.46153846, 35.26923077, 39.07692308, 42.88461538,
46.69230769, 50.5 , 54.30769231, 58.11538462,
61.92307692, 65.73076923, 69.53846154, 73.34615385,
77.15384615, 80.96153846, 84.76923077, 88.57692308,
92.38461538, 96.19230769, 100. ])
In [4]: a21 = a20.reshape(3,3,3)
In [5]: a21
Out[5]:
array([[[ 1. , 4.80769231, 8.61538462],
[ 12.42307692, 16.23076923, 20.03846154],
[ 23.84615385, 27.65384615, 31.46153846]],
[[ 35.26923077, 39.07692308, 42.88461538],
[ 46.69230769, 50.5 , 54.30769231],
[ 58.11538462, 61.92307692, 65.73076923]],
[[ 69.53846154, 73.34615385, 77.15384615],
[ 80.96153846, 84.76923077, 88.57692308],
[ 92.38461538, 96.19230769, 100. ]]])
In [6]: print(a21[(1,1,1)])
50.5
切片
用一個值採用方括號下標方式引用,而如果想要引用多個值的話,可以考慮做一個切片。比如s[1:3]就是由s[1]和s[2]組成的列表:
例:
In [10]: a22 = np.linspace(1,10,5)
In [11]: a22
Out[11]: array([ 1. , 3.25, 5.5 , 7.75, 10. ])
In [12]: print(a22[2:4])
[ 5.5 7.75]
多維的切片也是同理,比如我們從一個3x3x3的立方體中切出一個2x2x2的小立方體:
In [5]: a21
Out[5]:
array([[[ 1. , 4.80769231, 8.61538462],
[ 12.42307692, 16.23076923, 20.03846154],
[ 23.84615385, 27.65384615, 31.46153846]],
[[ 35.26923077, 39.07692308, 42.88461538],
[ 46.69230769, 50.5 , 54.30769231],
[ 58.11538462, 61.92307692, 65.73076923]],
[[ 69.53846154, 73.34615385, 77.15384615],
[ 80.96153846, 84.76923077, 88.57692308],
[ 92.38461538, 96.19230769, 100. ]]])
In [8]: slice1 = a21[1:3,1:3,1:3]
In [9]: slice1
Out[9]:
array([[[ 50.5 , 54.30769231],
[ 61.92307692, 65.73076923]],
[[ 84.76923077, 88.57692308],
[ 96.19230769, 100. ]]])
請注意,切片的語法不用元組,直接在方括號裡切就好了。
另外,切片可以使用負數做下標,-1就是右數第一個元素。最左和最右都可以不寫,比如從1到最右,可以寫成a[1:]
例:
In [11]: a22
Out[11]: array([ 1. , 3.25, 5.5 , 7.75, 10. ])
In [12]: print(a22[2:4])
[ 5.5 7.75]
In [13]: a22[1:]
Out[13]: array([ 3.25, 5.5 , 7.75, 10. ])
In [14]: a22[1:-1]
Out[14]: array([ 3.25, 5.5 , 7.75])
多維陣列的資料型別
在前面的學習中,我們並不在意資料型別,一樣也可以使用多維陣列。但是,有了型別之後,陣列可以更方便和更快速的操作。
我們前面所學習的生成陣列的方法,其實都可以預設帶一個dtype引數。
型別值常用的有int32, int64, uint32, uint64, float32, float64, complex64, complex128等。因為NumPy是個數學庫,精確的型別對於提高計算速度是很有益的。
例:
In [18]: a23 = np.logspace(1,10,5,base=2,dtype=np.float64)
In [19]: a23
Out[19]:
array([ 2. , 9.51365692, 45.254834 , 215.2694823 ,
1024. ])
對陣列的每個元素都進行計算
資料只有可以計算才有價值。我們學會了生成陣列,訪問陣列,下一步就是如何對陣列進行計算。
NumPy提供了大量的針對陣列進行運算的函式,比如X是一個陣列,np.sin(X)可以對陣列中每一個元素都進行sin運算。
例:
In [20]: a24 = np.linspace(0, np.pi/2, 10, dtype=np.float64)
In [21]: a24
Out[21]:
array([ 0. , 0.17453293, 0.34906585, 0.52359878, 0.6981317 ,
0.87266463, 1.04719755, 1.22173048, 1.3962634 , 1.57079633])
In [22]: a25 = np.sin(a24)
In [23]: a25
Out[23]:
array([ 0. , 0.17364818, 0.34202014, 0.5 , 0.64278761,
0.76604444, 0.8660254 , 0.93969262, 0.98480775, 1. ])
這是一行的,多行的也照樣管用,我們看個例子:
In [24]: a26 = np.linspace(0, np.pi*2, 16, dtype=np.float32)
In [25]: a26
Out[25]:
array([ 0. , 0.41887903, 0.83775806, 1.2566371 , 1.67551613,
2.09439516, 2.51327419, 2.93215322, 3.35103226, 3.76991129,
4.18879032, 4.60766935, 5.02654839, 5.44542742, 5.86430645,
6.28318548], dtype=float32)
In [27]: a27 = np.sin(a26.reshape(4,4))
In [28]: a27
Out[28]:
array([[ 0.00000000e+00, 4.06736642e-01, 7.43144870e-01,
9.51056540e-01],
[ 9.94521916e-01, 8.66025388e-01, 5.87785184e-01,
2.07911611e-01],
[ -2.07911789e-01, -5.87785363e-01, -8.66025448e-01,
-9.94521916e-01],
[ -9.51056480e-01, -7.43144751e-01, -4.06736493e-01,
1.74845553e-07]], dtype=float32)
陣列之間支援加減乘除,乘方,取餘。
例:給一個陣列的每個元素都乘以2
In [31]: a28 = np.array([1,2,3,4]).reshape(2,-1)
In [32]: a28
Out[32]:
array([[1, 2],
[3, 4]])
In [33]: a28*2
Out[33]:
array([[2, 4],
[6, 8]])
兩個陣列之間做加法:
In [35]: a29 = np.ones((2,2))
In [36]: a29
Out[36]:
array([[ 1., 1.],
[ 1., 1.]])
In [37]: a28+a29
Out[37]:
array([[ 2., 3.],
[ 4., 5.]])
不但算術運算可以做,也可以針對整個陣列做比較大小運算。
例:
In [38]: a29>a28
Out[38]:
array([[False, False],
[False, False]], dtype=bool)
彙總類的運算
除了對每個元素進行計算,我們還可以對這些元素進行彙總,比如求和sum,求平均值mean等。
例:
In [40]: np.sum(a28)
Out[40]: 10
In [41]: np.mean(a28)
Out[41]: 2.5
矩陣matrix
除了前面所講的多維陣列,NumPy還提供了矩陣類matrix. matrix的預設運算都是矩陣運算。
例:
In [45]: a30 = np.matrix(np.linspace(1,10,9,dtype=np.float64).reshape(3,-1))
In [46]: a30
Out[46]:
matrix([[ 1. , 2.125, 3.25 ],
[ 4.375, 5.5 , 6.625],
[ 7.75 , 8.875, 10. ]])
In [48]: a31 = np.matrix(np.ones((3,3)))
In [49]: a31
Out[49]:
matrix([[ 1., 1., 1.],
[ 1., 1., 1.],
[ 1., 1., 1.]])
In [50]: np.dot(a30,a31)
Out[50]:
matrix([[ 6.375, 6.375, 6.375],
[ 16.5 , 16.5 , 16.5 ],
[ 26.625, 26.625, 26.625]])
矩陣的逆陣,就可以直接用X**-1來表示。
例:
In [52]: a30 ** -1
Out[52]:
matrix([[ 9.38565300e+14, -1.87713060e+15, 9.38565300e+14],
[ -1.87713060e+15, 3.75426120e+15, -1.87713060e+15],
[ 9.38565300e+14, -1.87713060e+15, 9.38565300e+14]])
In [53]: a30
Out[53]:
matrix([[ 1. , 2.125, 3.25 ],
[ 4.375, 5.5 , 6.625],
[ 7.75 , 8.875, 10. ]])
In [54]: a30 * (a30 ** -1)
Out[54]:
matrix([[ 0.8125 , -0.125 , 0. ],
[ 0.15625, -1.0625 , 1. ],
[ 0. , 0. , 2. ]])
本文作者:lusing
本文為雲棲社群原創內容,未經允許不得轉載。