Numpy中陣列array和矩陣matrix區別
阿新 • • 發佈:2019-02-01
NumPy的主要物件是同種元素的多維陣列。這是一個所有的元素都是一種型別、通過一個正整數元組索引的元素表格(通常是元素是數字)。
- 在NumPy中維度(dimensions)叫做軸(axes),軸的個數叫做秩(rank),和線性代數中的秩不是一樣的;
- 在用python求線代中的秩中,我們用numpy包中的linalg.matrix_rank方法計算矩陣的秩。
import numpy as np
i = np.matrix(np.eye(4))
print(type(i))
print(np.linalg.matrix_rank(i))
i = np.eye(4)
print (type(i))
print(np.linalg.matrix_rank(i))
輸出:
<class 'numpy.matrixlib.defmatrix.matrix'>
4
<class 'numpy.ndarray'>
4
matrix是array的分支,matrix和array在很多時候都是通用的,你用哪一個都一樣。但這時候,官方建議大家如果兩個可以通用,那就選擇array,因為array更靈活,速度更快,很多人把二維的array也翻譯成矩陣。
但是matrix的優勢就是相對簡單的運算子號,比如兩個矩陣相乘,就是用符號*,但是array相乘不能這麼用,得用方法.dot() array的優勢就是不僅僅表示二維,還能表示3、4、5…維,而且在大部分Python程式裡,array也是更常用的。
numpy使用注意事項
在python中,可以使用numpy中array建立一個narray物件,我們可以使用dot(a,b)或者@進行普通矩陣乘法,或者使用multipy(a,b)或者*進行數量積操作。
在python建立一個numpy.array([1,2,3])他是一個行向量,shape = (3,)具體來說退化成一個數組,他是可以看做一個行向量或者列向量,具體要看他是在矩陣乘法的左邊還是右邊,下面進行測試
1. 叉乘運算
import numpy as np
a = np.array([[1,0,0],[0,1,0],[0,0,1]]) # (3 * 3)
b = np.array([1 ,2,3]) # (3,) 拋開線性代數的行向量和列向量,這裡他是二者都可以的
c1 = a @ b # 這裡是作為一個列向量,(3*3) @ (3,1) = (3,) 結果是一個列向量,但是python中顯示都(3,)
c2 = b @ a # 這裡是作為一個行向量的, (1 * 3)@ (3 *3) = (1 * 3) 結果還是顯示(3,)
print(c2)
輸出:
[[1 0 0]
[0 1 0]
[0 0 1]]
[1 2 3]
import numpy as np
a = np.array([[1,0,2],[0,0,1],[0,0,1]]) # (3 * 3)
b = np.array([1,2,1]) # (3,) 拋開線性代數的行向量和列向量,這裡他是二者都可以的
c1 = a * b # 相當於[1,2,1]這個數作用於每一列
c2 = b * a # 這裡是作為一個行向量的, (1 * 3)@ (3 *3) = (1 * 3) 結果還是顯示(3,)
# 這裡的 c1 = c2
輸出:
[[1 0 2]
[0 0 1]
[0 0 1]]
2. 數量積運算
import numpy as np
a = np.mat([[1,0,0],[0,1,0],[0,0,1]]) # (3 * 3)
b = np.mat([1,2,3]) # 這裡的matrix和ndarray是不同的,他是直接輸出了(1 × 3)表示這完全是一個行向量
#b = b.reshape(3,1) # 可以進行reshape把行向量變成列向量
c = a * b # 這裡注意一下,在matrix中*表示的就是叉乘,但是這裡的話 (3×3)* (1*3)出現了矩陣維度不匹配的狀況
# 可以把b變成一個列向量就可以了
出現錯誤:
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-22-88c7ec17eabb> in <module>()
4 b = np.mat([1,2,3]) # 這裡的matrix和ndarray是不同的,他是直接輸出了(1 × 3)表示這完全是一個行向量
5 #b = b.reshape(3,1)
----> 6 c = a * b # 這裡注意一下,在matrix中*表示的就是叉乘,但是這裡的話 (3×3)* (1*3)出現了矩陣維度不匹配的狀況
7 # 可以把b變成一個列向量就可以了
/usr/local/anaconda3/lib/python3.6/site-packages/numpy/matrixlib/defmatrix.py in __mul__(self, other)
307 if isinstance(other, (N.ndarray, list, tuple)) :
308 # This promotes 1-D vectors to row vectors
--> 309 return N.dot(self, asmatrix(other))
310 if isscalar(other) or not hasattr(other, '__rmul__') :
311 return N.dot(self, other)
ValueError: shapes (3,3) and (1,3) not aligned: 3 (dim 1) != 1 (dim 0)
c = b * a # (1*3) @ (3*3) = (1*3)這種是對的
print(c.shape)
輸出:
(3, 1)
c = np.multiply(a,b) # 在matrix中,我們需要使用multiply函式來計算二個矩陣的數量積
print(c)
輸出:
[[1 0 0]
[0 2 0]
[0 0 3]]
3. 混合使用
import numpy as np
a = np.array([1,1,1])
b = np.array([1,1,1])
c = a @ b # 這裡我們知道了python中ndarray預設是一個行向量,但是他也是會發生變化的,比如這裡我們@右邊的自動變成了一個列向量
print(c)
輸出:
3
3.1 下面簡單測試一下@符號是否可以在matrix中進行使用
import numpy as np
a = np.mat([[1],[1],[1]]) # a = (3 * 1)
b = np.mat([1,1,1]) # b = (1 * 3)
c1 = a @ b # 經過測試@確實是可以表示叉乘的對於matrix來說,(1 * 3) @ (3 * 1) = (3 * 3)
c2 = a * b # 這個也是表示叉乘的
print(c1==c2)
輸出:
[[ True True True]
[ True True True]
[ True True True]]
問題: 現在我們要實現 (1 × 2) 和 (1 × 3)矩陣相乘,我們怎麼實現了?
一種直觀的做法就是 (1 × 2)轉置和(1 ×3)相乘就可以了。
import numpy as np
a = np.array([1,1]) # (1,2)
b = np.array([1,1,1]) # (1,3)
c = a @ b # 從前面討論可以知道,這裡a是一個行向量,@之後b是一個列向量,也就是c =(1*2) @ (3*1) 當然是出現了型別不匹配了啊!
輸出:
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-33-9e4dd8a641b5> in <module>()
2 a = np.array([1,1]) # (1,2)
3 b = np.array([1,1,1]) # (1,3)
----> 4 c = a @ b
ValueError: shapes (2,) and (3,) not aligned: 2 (dim 0) != 3 (dim 0)
3.2 .T轉置是否對一維向量起作用
3.2.1 首先是numpy中的array(不起作用)
import numpy as np
a = np.array([[1,1,1],[1,1,1]]) # (2*3)
print(a.T.shape) # (3*2) 這裡表示.T
輸出:
(3, 2)
import numpy as np
a = np.array([1,1,1])
print(a.shape) # (3,)
print(a.T.shape) # (3,) 這裡輸出的結果是一樣的,表示轉置操作對一維向量對numpy中的array不起作用
輸出:
(3,)
(3,)
3.2.2 numpy中matrix(起作用)
import numpy as np
a = np.mat([[1,1,1]])
print(a.shape) # (1*3) # 這裡是起作用的
print(a.T.shape) # (3*1)
輸出:
(1, 3)
(3, 1)
所以我們針對上面的問題,我們可以進行以下操作來實現(1*2).T和(1*3)相乘得到(2*3)矩陣
import numpy as np
a = np.array([1,1]) # (1,2)
b = np.array([1,1,1]) # (1,3)
c = (np.matrix(a).T) @ (np.matrix(b)) # 我們可以藉助matrix()將numpy中ndarray轉換成matrix進行普通矩陣的操作!
print(c)
輸出:
[[1 1 1]
[1 1 1]]
注意:
我們在實際程式設計中,可以輸出每一步的資料維度,這樣我們在進行矩陣乘法的時候,就不會弄混