Python 中矩陣運算主要使用numpy庫。NumPy的主要對象是同種元素的多維數組。這是一個所有的元素都是一種類型、通過一個正整數索引的元素表格(通常是元素是數字)。因此對於隨機查找來說,比python自帶的list快很多。
在numpy里面通常使用兩個變量:array和matrix。其實python標准類庫中也有array,但是它的功能相對numpy的少很多,所以不用。matrix是array的分支,matrix可以看做二維的array,array可以是多維,matrix和array在很多時候都是通用的。官方建議如果兩個都可以用,那就選擇array,因為array更靈活,速度更快,很多人把二維的array也翻譯成矩陣。但是matrix的優勢在於,它相對於array使用的符號更簡潔一些。
矩陣和向量的創建
a = np.array([2,4,5,6,7])
如上創建了一個1*5的一行5列的array,這就相當於一個行向量(實際上不是,應該用np.array([[2,4,5,6,7]])創建)。
m = np.matrix([[1,2,4,5,6],[5,6,8,9,4]])
如上創建了一個2*5的matrix,這就是一個2*5的矩陣。
另外矩陣還可以通過這個創建:
m = np.mat([[1,2,4,5,6],[5,6,8,9,4]])
mat和matrix的相關之處是,mat([])就等同於matrix([],copy=false),而matrix([])實際上默認copy=true。
所以如果想引用一個矩陣,如m,可以使用a = mat(m),或者a = matrix(m,copy=false)。當然用[]列表來新創建一個矩陣的時候它們是完全一樣的。
轉置
m = m.transpose()
m = m.T
matrix和除一維外的array可以通過這個兩個進行轉置(T和transpose不同點暫時不研究了)。
對於一維的array,它不是矩陣,也不是向量,所以不能通過transpose來轉置。因為在計算機里,二維和一維定義好以后就確定下來用幾個索引標志來索引了。而向量從功能上來看,應該被看做1行或1列的矩陣,所以它應該是二維的。就是說我們索引它的某個元素,比如行向量a的第3個元素,我們應該用a[0][3],而不是a[3]。所以a = np.array([2,4,5,6,7])創建的其實啥也不是,像np.array([[2,4,5,6,7]])這樣創建二維的才算真正意義上的行向量,也就能用transpose()來轉置了。
如果用a = np.array([2,4,5,6,7,1,3,8])創建了一行數組a,想變成向量,要先用reshape()函數將它變成二維向量。
高維張量轉置
x = np.transpose(x,(2,0,1))
以上例子是對三維張量x進行轉置,(2,0,1)的意思是:將張量從(x,y,z)軸轉置為(z,x,y)軸。也就是說,如果張量x的形狀是[2,3,4],轉換后就變成了[4,2,3]。
轉置效果實際上就是將張量各個軸的順序改變,而張量內部元素在各個軸上的索引並不會改變。也就是說,x內部有個元素索引是x[1,2,3],經過以上轉置,它的索引變為了x[3,1,2],在各個軸上的索引沒變,只是變了順序。
如果不填元組參數:
x = np.transpose(x)
等價於:
x = np.transpose(x,(2,1,0))
也就是直接將三個軸順序倒序。
更高維的張量類似。
reshape()函數
reshape()將一定規模的數組從一個形狀改為另一個形狀,並且不論你怎么改變形狀,數組中元素的先后位置都是從一開始就確定的。用法如下:
a = np.ones([8])
a = a.reshape([2,2,2])
將原本為一維的向量a變成了2*2*2的三維立方陣。如果將a賦值給一個新變量b:
b = a.reshape([2,2,2])
a的shape不變,b是2*2*2的立方陣,而且它們共享內存,即當a改變它的元素值時,b中對應的元素也會改變。另外,因為數組的規模是固定的,因此可以有一個維度為未知,輸入-1:
b = a.reshape([2,2,-1])
這樣的效果和上面是一致的。
矩陣乘法
乘法有三種表達方式:*、dot()、multiply()
np.multiply()
數組或矩陣的對應位置元素相乘。
np.dot()
對於一維數組array,執行對應位置相乘,然后再求和;對於秩不為1的二維數組(array)、矩陣(matrix),執行矩陣乘法運算(超過二維的可以參考numpy庫介紹)
乘法運算*
對數組array執行對應位置元素相乘(相當於 np.multiply() 函數),對矩陣matrix執行矩陣乘法運算(相當於 np.dot() 函數)。就是multiply()和dot()的融合。
冪運算**
相當於多個array或matrix執行*,即A**3=A*A*A。
總結
multiply()全都是對應元素相乘;dot()是矩陣乘法,而一維array是對應元素相乘后之和;*對array是對應元素相乘,對matrix是矩陣乘法。
相對來說matrix注重矩陣操作,array注重陣列操作(陣中元素對應進行運算)
矩陣特征值與特征向量
np.linalg.eig(A)
返回矩陣A的特征值和特征向量數組:
np.linalg.eig(A)[0]是特征值數組,沒有大小順序;
np.linalg.eig(A)[1]是特征向量,與特征值數組相對應。