矩陣的定義
矩陣的運算(含冪運算)
加減比較簡單,就是對應元素相加減 (只有行列都相同的矩陣
才可以進行)
用NumPy 來演示一下矩陣加法
Numpy有專門的矩陣函數(np.mat)
import numpy as np # 創建兩個集合 A = np.arange(1,10).reshape((3,3)) B = np.arange(9).reshape((3,3)) print(A) print("-"*5) print(B)
輸出
[[1 2 3] [4 5 6] [7 8 9]] ----- [[0 1 2] [3 4 5] [6 7 8]]
A + B
輸出:
array([[ 1, 3, 5], [ 7, 9, 11], [13, 15, 17]])
A - B
輸出:
array([[1, 1, 1], [1, 1, 1], [1, 1, 1]])
# 之前說過 ”只有行列都相同的矩陣才可以進行“ 來驗證一下 # 創建一個2行3列的矩陣 C = np.arange(6).reshape((2,3)) D = np.arange(6).reshape((3,2)) print(C) print("-"*5) print(D)
輸出:
[[0 1 2] [3 4 5]] ----- [[0 1] [2 3] [4 5]]
C + D # 不同形狀的矩陣不能進行加運算
輸出:
---------------------------------------------------------------------------
ValueError Traceback (most recent call last) <ipython-input-8-bc97e29f7e31> in <module>() 1 # 2行3列的矩陣 + 3行2列的矩陣 ----> 2C + D # 不同形狀的矩陣不能進行加運算
.數乘、數除
這個也比較簡單,就是和每個元素相乘,eg:2×A
,A原本的每一個元素都擴大了兩倍
數除其實就是乘以倒數(1/x)
print(A)
[[1 2 3] [4 5 6] [7 8 9]]
2 * A
array([[ 2, 4, 6], [ 8, 10, 12], [14, 16, 18]])
A / 2
array([[0.5, 1. , 1.5], [2. , 2.5, 3. ], [3.5, 4. , 4.5]])
.矩陣乘法
兩個矩陣的乘法僅當第一個矩陣A的列數(column)和另一個矩陣B的行數(row)相等才可以進行計算
程序驗證了我們上面的運算結果,還得注意一下:
A×B
和B×A
是不一樣的,eg:B×A
.冪乘、冪運算
冪乘比較簡單,就是每個元素開平方,不一定是方陣
必須是方陣才能進行冪運算,比如A²=A×A
(矩陣相乘前提:第一個矩陣A的行=第二個矩陣A的列==>方陣
)
來個小結 + 擴展:
矩陣的加法運算滿足交換律:A + B = B + A
矩陣的乘法滿足結合律和對矩陣加法的分配律:
結合律:(AB)C = A(BC)
左分配律:(A + B)C = AC + BC
右分配律:C(A + B) = CA + CB
矩陣的乘法與數乘運算之間也滿足類似結合律的規律;與轉置之間則滿足倒置的
分配律:c(A + B) = cA + cB
結合律:c(AB) = (cA)B = A(cB)
矩陣乘法不滿足交換律 一般來說,矩陣A及B的乘積AB存在,但BA不一定存在,即使存在,大多數時候AB ≠ BA
.特殊矩陣
import numpy as np # 一維 # 可以指定類型 np.zeros(5,dtype=int) print(np.zeros(5)) # 完整寫法:np.zeros((5,)) print("********************\n") # 二維 print(np.zeros((2,5)))# 建議用元組,官方文檔都是元組 print("********************\n") # 三維 ==> 可以這么理解,2個2*5(2行5列)的矩陣 print(np.zeros((2,2,5))) print("********************\n") # `np.ones(tuple)` 用法和`np.zeros(tuple)`差不多 # 可以指定類型 np.ones(5,dtype=int) # 一維 print(np.ones(5)) # 完整寫法 np.ones((5,)) print("********************\n") # 二維,傳一個shape元組 print(np.ones((2,5))) print("********************\n") # 三維 可以理解為兩個二維數組 print(np.ones((2,2,5))) print("********************\n") ################ 指定值矩陣 ################ # 創建指定值的矩陣: print(np.full((3,5),222)) print("********************\n") # 創建指定值的矩陣,浮點類型 print(np.full((3,5),222.0)) print("********************\n")
輸出:
[0. 0. 0. 0. 0.]
********************
[[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]]
********************
[[[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]]
[[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]]]
********************
[1. 1. 1. 1. 1.]
********************
[[1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1.]]
********************
[[[1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1.]]
[[1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1.]]]
********************
[[222 222 222 222 222]
[222 222 222 222 222]
[222 222 222 222 222]]
********************
[[222. 222. 222. 222. 222.]
[222. 222. 222. 222. 222.]
[222. 222. 222. 222. 222.]]
********************
轉置矩陣
轉置矩陣 :將矩陣的行列互換得到的新矩陣(行列式不變)
m行×n列
的矩陣行和列交換后就變成了n行×m列
的矩陣,eg:3行×2列
==> 2行×3列
再次提醒:兩個矩陣的乘法僅當第一個矩陣A的列數(column)和另一個矩陣B的行數(row)相等才可以進行計算
import numpy as np A = np.arange(6).reshape((2,3)) print("\nA: \n",A) # 轉置矩陣(行列互換) A.T print("\nA.T: \n",A.T) B = np.random.randint(10,size=(2,3)) print("\nB: \n",B) print("-"*5) print("\nB.T: \n",B.T) ################ 驗證系列 ################ # 驗證一下(A+B)^T=A^T+B^T print("\nA.T + B.T: \n",A.T + B.T) print("-"*5) print("\n(A+B).T: \n",(A+B).T) # 驗證一下(A+B)^T=A^T+B^T # 其實也再一次驗證了,Numpy運算符默認是對每一個元素的操作 print("\n(A+B).T == A.T + B.T: \n",(A+B).T == A.T + B.T) # 把A變成3*2的矩陣,不夠元素用0補 # reshape:有返回值,不對原始多維數組進行修改 # resize:無返回值,會對原始多維數組進行修改 A.resize(3,2) print("\nB: \n",B) print("\nA: \n",A) print("\nnp.power(A,3): \n",np.power(A,3)) # A*A*A C=np.arange(1,5).reshape(2,2) D=np.linalg.matrix_power(C,3) print("\n C:",C) print("\n D:",D)
A:
[[0 1 2]
[3 4 5]]
A.T:
[[0 3]
[1 4]
[2 5]]
B:
[[3 1 8]
[5 4 8]]
-----
B.T:
[[3 5]
[1 4]
[8 8]]
A.T + B.T:
[[ 3 8]
[ 2 8]
[10 13]]
-----
(A+B).T:
[[ 3 8]
[ 2 8]
[10 13]]
(A+B).T == A.T + B.T:
[[ True True]
[ True True]
[ True True]]
B:
[[3 1 8]
[5 4 8]]
A:
[[0 1]
[2 3]
[4 5]]
np.power(A,3):
[[ 0 1]
[ 8 27]
[ 64 125]]
C: [[1 2]
[3 4]]
D: [[ 37 54]
[ 81 118]]
上三角矩陣和下三角矩陣
import numpy as np # 創建一個5行4列矩陣 A = np.random.randint(10,size=(4,4)) print("\nA: \n",A) # 上三角 np.triu(A) print("\nnp.triu(A): \n",np.triu(A)) # 下三角 np.tril(A) print("\nnp.tril(A): \n",np.tril(A)) # 驗證一下最后一個性質 # 三角矩陣的逆矩陣也仍然是三角矩陣 print("\nnp.triu(A).T: \n",np.triu(A).T) print('-'*5) print("\nnp.tril(A).T: \n",np.tril(A).T)
A:
[[9 9 5 7]
[0 4 6 6]
[1 4 9 7]
[2 4 5 2]]
np.triu(A):
[[9 9 5 7]
[0 4 6 6]
[0 0 9 7]
[0 0 0 2]]
np.tril(A):
[[9 0 0 0]
[0 4 0 0]
[1 4 9 0]
[2 4 5 2]]
np.triu(A).T:
[[9 0 0 0]
[9 4 0 0]
[5 6 9 0]
[7 6 7 2]]
-----
np.tril(A).T:
[[9 0 1 2]
[0 4 4 4]
[0 0 9 5]
[0 0 0 2]]
對角矩陣
import numpy as np # 簡單創建 A=np.diag([3,9,6]) print("\nA: \n",A) B=np.diag([2,2,2]) print("\nB: \n",B) # 獲取對角元素,然后再生成對角矩陣 C= np.random.randint(10,size=(4,4)) D = np.diag(C.diagonal()) #或者 np.diag(np.diag(A)) print("\nC: \n",C) print("\nD: \n",D) # 對角矩陣的矩陣冪運算等於其對應元素的冪運算 D**3 E=D.dot(D).dot(D) print("\nE: \n",E)
A:
[[3 0 0]
[0 9 0]
[0 0 6]]
B:
[[2 0 0]
[0 2 0]
[0 0 2]]
C:
[[6 6 0 7]
[5 9 1 4]
[9 1 1 0]
[5 0 6 9]]
D:
[[6 0 0 0]
[0 9 0 0]
[0 0 1 0]
[0 0 0 9]]
E:
[[216 0 0 0]
[ 0 729 0 0]
[ 0 0 1 0]
[ 0 0 0 729]]
.單位矩陣
#定義一個2行的單位矩陣(列默認和行一致) # np.eye(rows,columns=rows) A=np.eye(2) print("\nA: \n",A) # 可以指定類型 B = np.eye(4,dtype=int) print("\nB: \n",B) C=np.random.randint(10,size=(4,4)) print("\nC: \n",C) D=C.dot(B) print("\nD: \n",D)
A:
[[1. 0.]
[0. 1.]]
B:
[[1 0 0 0]
[0 1 0 0]
[0 0 1 0]
[0 0 0 1]]
C:
[[6 3 1 4]
[2 3 8 2]
[5 4 3 0]
[3 9 6 4]]
D:
[[6 3 1 4]
[2 3 8 2]
[5 4 3 0]
[3 9 6 4]]
對稱矩陣
對稱矩陣 :元素以主對角線為對稱軸對應相等的方陣
對稱矩陣的轉置是它本身:AT=A
import numpy as np A = np.random.randint(10,size=(4,4)) print("\nA: \n",A) #上矩陣 B = np.triu(A) print("\nB: \n",B) #對稱矩陣 C = B + B.T - np.diag(A.diagonal()) print("\nC: \n",C)
A:
[[3 8 5 4]
[3 2 0 7]
[4 4 7 8]
[2 5 9 8]]
B:
[[3 8 5 4]
[0 2 0 7]
[0 0 7 8]
[0 0 0 8]]
C:
[[3 8 5 4]
[8 2 0 7]
[5 0 7 8]
[4 7 8 8]]
逆矩陣
消元法
可能一看到逆矩陣,大家就想到代數余子式 ,不過逆天要說的是,代數余子式就和我們程序員面試題一樣,有些題目就是又繁瑣實際運用又沒多大意義的題目一樣,很多時候面試官都不看面試題一眼,同樣的那些出題老師自己解題一般都不會使用。我這邊介紹一下方便簡單的方法“消元法”
# coding=utf-8 import numpy as np A = np.array([[3,2],[1,2]]) print("\nA: \n",A) B=np.linalg.inv(A) print("\nB: \n",B)
A:
[[3 2]
[1 2]]
B:
[[ 0.5 -0.5 ]
[-0.25 0.75]]
二階方陣公式
偽逆矩陣
程序比較簡單:
np.linalg.det(A)
# coding=utf-8 import numpy as np #A非方陣 A = np.array([[7, 3, 6],[5, 3, 1]]) print("\nA: \n",A) # 有時候還是需要求逆矩陣 # 那就可以求它的偽逆矩陣 B=np.linalg.pinv(A) print("\nB: \n",B) # A*X*A=A C=A.dot(B).dot(A) print("\nC: \n",C) # X*A*X=X D=B.dot(A).dot(B) print("\nD: \n",D) # 創建一個矩陣 E = np.mat([[3,2],[1,2]]) print("\nE: \n",E) # np.linalg.det(E)不等於0就是可逆 print(np.linalg.det(E)) #4.000000000000001 #E的逆矩陣F print("\nE.I: \n",E.I) F=np.linalg.inv(E) print("\nF: \n",F) G=E*F print("\nG: \n",G) print("\nE.T: \n",E.T)
A:
[[7 3 6]
[5 3 1]]
B:
[[-0.00632911 0.15189873]
[-0.05696203 0.16708861]
[ 0.20253165 -0.26075949]]
C:
[[7. 3. 6.]
[5. 3. 1.]]
D:
[[-0.00632911 0.15189873]
[-0.05696203 0.16708861]
[ 0.20253165 -0.26075949]]
E:
[[3 2]
[1 2]]
4.000000000000001
E.I:
[[ 0.5 -0.5 ]
[-0.25 0.75]]
F:
[[ 0.5 -0.5 ]
[-0.25 0.75]]
G:
[[1.00000000e+00 2.22044605e-16]
[1.11022302e-16 1.00000000e+00]]
E.T:
[[3 1]
[2 2]]