1. 程式人生 > >Numpy中陣列array和矩陣matrix區別

Numpy中陣列array和矩陣matrix區別

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
  1. matrix是array的分支,matrix和array在很多時候都是通用的,你用哪一個都一樣。但這時候,官方建議大家如果兩個可以通用,那就選擇array,因為array更靈活,速度更快,很多人把二維的array也翻譯成矩陣。

  2. 但是matrix的優勢就是相對簡單的運算子號,比如兩個矩陣相乘,就是用符號*,但是array相乘不能這麼用,得用方法.dot() array的優勢就是不僅僅表示二維,還能表示3、4、5…維,而且在大部分Python程式裡,array也是更常用的。

numpy使用注意事項

  1. 在python中,可以使用numpy中array建立一個narray物件,我們可以使用dot(a,b)或者@進行普通矩陣乘法,或者使用multipy(a,b)或者*進行數量積操作。

  2. 在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]]

注意:

我們在實際程式設計中,可以輸出每一步的資料維度,這樣我們在進行矩陣乘法的時候,就不會弄混