NumPy 1.14 教學 – #03 基本操作(加減乘除、矩陣乘法、取代)
開始學NumPy之前至少先熟悉Python基礎使用方法,這樣再來看NumPy才不會那麼吃力!
Python3 教學、筆記本文將會介紹NumPy矩陣之間的加減乘除(包含矩陣乘法)、取代、屬性以及常用方法(dot, sum, min, max, mean, cumsum, sqrt, add, exp, …)!
本文章的練習檔同步存放於GitHub:Learn NumPy – GitHub
基礎運算-1
加、減、次方的計算非常直覺好懂,分別使用『 + 、 – 、 ** 』就可以了。
例如:加、減、次方都可以直接做單一數值的同加、同減、次方。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
print('維度相同的矩陣相加、減:') # 維度相同的矩陣相加、減 a = np.array( [6, 7, 8, 9] ) b = np.arange( 4 ) c = a - b print("a=>{0}".format(a)) print("b=>{0}".format(b)) print("c=>{0}".format(c)) print('\n同加、同減一個數值:') # 同加、同減一個數值 a += 5 print("a=>{0}".format(a)) b -= 5 print("b=>{0}".format(b)) print('\n次方:') # d是b的2次方 # d is squared of b. d = b**2 print("d=>{0}".format(d)) |
1 2 3 4 5 6 7 8 9 10 11 |
維度相同的矩陣相加、減: a=>[6 7 8 9] b=>[0 1 2 3] c=>[6 6 6 6] 同加、同減一個數值: a=>[11 12 13 14] b=>[-5 -4 -3 -2] 次方: d=>[25 16 9 4] |
基礎運算-2
矩陣(matrix)同乘上某個特定純量(scalar)也很簡單,就直接相乘就好了!
1 2 3 4 5 6 7 8 9 10 11 12 13 |
a = np.arange(5) b = np.arange(10, 5, -1) print("a=>{0}".format(a)) print("b=>{0}".format(b)) print("\n同除:") # c等於a同除以2 c = a / 2 print("c=>{0}".format(c)) print("\n同乘:") # d等於b同乘以2 d = b * 2 print("d=>{0}".format(d)) |
1 2 3 4 5 6 7 8 |
a=>[0 1 2 3 4] b=>[10 9 8 7 6] 同除: c=>[0. 0.5 1. 1.5 2. ] 同乘: d=>[10 9 8 7 6] |
矩陣運算
$A=
\begin{bmatrix}
1 & 2 \\
3& 4
\end{bmatrix},\space
B=
\begin{bmatrix}
5 & 6 \\
7 & 8
\end{bmatrix}
$
矩陣乘法:
$A\times B=
\begin{bmatrix}
\begin{bmatrix} 1 \times 5 + 2 \times 7 \end{bmatrix} & \begin{bmatrix} 1 \times 6 + 2 \times 8 \end{bmatrix} \\
\begin{bmatrix} 3 \times 5 + 4 \times 7 \end{bmatrix} & \begin{bmatrix} 3 \times 6 + 4 \times 8 \end{bmatrix}
\end{bmatrix}
$
$=
\begin{bmatrix}
\begin{bmatrix} 5 + 14 \end{bmatrix} & \begin{bmatrix} 6 + 16 \end{bmatrix} \\
\begin{bmatrix} 15 + 28 \end{bmatrix} & \begin{bmatrix} 18 + 32 \end{bmatrix} \\
\end{bmatrix}
$
$=
\begin{bmatrix}
19 & 22 \\
43 & 50
\end{bmatrix}
$
矩陣相對應位置相乘:
$=
\begin{bmatrix}
1\times 5 & 2\times 6 \\
3\times 7 & 4\times 8
\end{bmatrix}=
\begin{bmatrix}
5 & 12 \\
21 & 32
\end{bmatrix}
$
1 2 3 4 5 6 |
# 矩陣相乘 A = np.array([[1, 2], [3, 4]]) B = np.array([[5, 6], [7, 8]]) print("A, B相乘(矩陣乘法) =>\n{0}".format(A.dot(B))) print() print("A, B相對應位置相乘=>\n{0}".format(A*B)) |
1 2 3 4 5 6 7 |
A, B相乘(矩陣乘法) => [[19 22] [43 50]] A, B相對應位置相乘=> [[ 5 12] [21 32]] |
取代
這個也很常用到喔,像是有時候要把矩陣裡面NaN的數值取代成0的時候就很好用!
舉例:判斷陣列元素值小於等於0的元素,把那些元素的數值取代成1
1 2 3 4 5 6 7 |
# 印出陣列中小於等於0的元素 e = np.array([5, -1, 3, 9, 0]) print("陣列e裡面哪幾個位置的元素值小於等於零?:{0}".format(e<=0)) # 把小於等於0的元素取代成1 e[e<=0] = 1 print("把小於等於0的元素取代成1=>{0}".format(e)) |
1 2 |
陣列e裡面哪幾個位置的元素值小於等於零?:[False True False False True] 把小於等於0的元素取代成1=>[5 1 3 9 1] |
常犯錯誤
因為NumPy太好用了,導致有時候甚至會忽略兩個要做運算的陣列型別根本不符,最後就會出錯~哈
用下列例子給大家了解這種狀況:
1 2 3 4 5 6 7 8 9 10 |
## Operations: += *= a = np.ones((2, 3), dtype=np.float) b = np.random.random( (2,3) ) a *= 5 print("a=>\n{0}".format(a)) b += a print("b=>\n{0}".format(b)) a += b print("a=>\n{0}".format(a)) |
1 2 3 4 5 6 7 8 9 |
a=> [[5. 5. 5.] [5. 5. 5.]] b=> [[5.0523616 5.43059437 5.62231546] [5.75642265 5.38043447 5.12177101]] a=> [[10.0523616 10.43059437 10.62231546] [10.75642265 10.38043447 10.12177101]] |
如果把上面範例第二行程式的 np.float 改成 np.int 就會出錯喔!
下列程式第11行:硬是用型別為int的矩陣加上一個型別為float的矩陣,肯定會出錯的吧!
1 2 3 4 5 6 7 8 9 10 11 12 |
## Operations: += *= a = np.ones((2, 3), dtype=np.int) b = np.random.random( (2,3) ) a *= 5 print("a=>\n{0}".format(a)) b += a # float64 = float64 + int64 print("b=>\n{0}".format(b)) # int64 = int64 + float64 a += b print("a=>\n{0}".format(a)) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
a=> [[5 5 5] [5 5 5]] b=> [[5.38047447 5.23668611 5.9057241 ] [5.62997161 5.45062956 5.12463863]] --------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-18-ac31fc386fa0> in <module>() 9 10 # int64 = int64 + float64 ---> 11 a += b 12 print("a=>\n{0}".format(a)) TypeError: Cannot cast ufunc add output from dtype('float64') to dtype('int64') with casting rule 'same_kind' |
常用方法-1
NumPy矩陣本身在初始化之後就內建一些好用的方法!
sum:矩陣加總
min:矩陣最小值
max:矩陣最大值
mean:矩陣平均值
1 2 3 |
## Methods: sum, min, max, mean a = np.random.random((3, 3)) print("sum=>{0}\nmax=>{1}\nmin=>{2}\nmean=>{3}".format(a.sum(), a.max(), a.min(), a.mean())) |
1 2 3 4 |
sum=>4.749391952733504 max=>0.9580529936101387 min=>0.13855036514445263 mean=>0.5277102169703893 |
常用方法-2
sum:axis=0或1 算是進階用法,可以指定要加總的維度是哪一個
cumsum:這是可以拿來對陣列值做出累計加總的效果,可以用在一維陣列上,數值就可以直接拿來畫出累計趨勢圖喔~
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
b = np.arange(12).reshape(2, 6) print("b=>\n{0}".format(b)) print() # 加總每一欄(column) print("b.sum(axis=0)=>{0}".format(b.sum(axis=0))) print() # 加總每一列(row) print("b.sum(axis=1)=>{0}".format(b.sum(axis=1))) print() revenu = np.round(np.random.random((1,12)) * 100, 0) print("revenu=>\n{0}".format(revenu)) print() # 累計加總(每一項數值等於自己加上前一項) print("Cumulative Sum of revenu=>\n{0}".format(revenu.cumsum())) |
1 2 3 4 5 6 7 8 9 10 11 12 13 |
b=> [[ 0 1 2 3 4 5] [ 6 7 8 9 10 11]] b.sum(axis=0)=>[ 6 8 10 12 14 16] b.sum(axis=1)=>[15 51] revenu=> [[57. 53. 51. 42. 52. 61. 61. 30. 30. 14. 93. 62.]] Cumulative Sum of revenu=> [ 57. 110. 161. 203. 255. 316. 377. 407. 437. 451. 544. 606.] |
常用方法-3
np.sqrt:矩陣內所有元素開平方根
np.exp:矩陣內所有元素進行Exponential function($e$)運算
np.add:矩陣或陣列相加
1 2 3 4 5 6 7 8 9 |
B = np.arange(3) B_exp = np.exp(B) print("B_exp=> {0}".format(B_exp)) B_sqrt = np.sqrt(B) print("B_sqrt=> {0}".format(B_sqrt)) C = np.array([2, 1, 0]) print("np.add(B, C)=> {0}".format(np.add(B, C))) |
1 2 3 |
B_exp=> [1. 2.71828183 7.3890561 ] B_sqrt=> [0. 1. 1.41421356] np.add(B, C)=> [2 2 2] |
還有很多常用的方法:
all, any, apply_along_axis, argmax, argmin, argsort, average, bincount, ceil, clip, conj, corrcoef, cov, cross, cumprod, cumsum, diff, dot, floor, inner, inv, lexsort, max, maximum, mean, median, min, minimum, nonzero, outer, prod, re, round, sort, std, sum, trace, transpose, var, vdot, vectorize, where
第一個A*B矩陣算錯了吧
是的,我搞錯了,感謝您的提醒!
d等於b同乘以2
d = b * 2
print(“d=>{0}”.format(b))
b->d
有時候邊寫邊舉例,結果改了卻忘記改範例程式碼…謝謝你!
加總每一列(row)
print(“b.sum(axis=0)=>{0}”.format(b.sum(axis=1)))
.sum(axis=0) 0->1
感謝你發現這些錯誤,我修正了!