詳解numpy中array類型和matrix類型

詳解numpy中array類型和matrix類型

Numpy中兩大重要類型array類型(N維數組ndarray)和矩陣類型matrix是很多基於Numpy數值計算的基礎,因此搞清楚兩者的關係是相當重要的, 特別是程序中混雜了這兩種類型,還夾帶着一些加減乘除的運算,那簡直有一種剪不斷理還亂的感覺,時不時腦袋就飛出一句話:尼瑪,程序又不聽話了!

咱們來捋一捋他們之間的關係, 首先Numpy中最重要的數據結構就是ndarry,簡寫爲array, 即N維數組,matrix其實也是一種array,只不過是維數爲2的特殊array,matrix的維數是固定的,這點和一般array顯著不同,即便加減乘除各種運算,matrix的維數不會發生變化,而array在運算時特別是歸約時維數會發生變化,一句話,matrix的維數永遠是2.

首先二者之間的轉化,array轉matrix用np.asmatrix或者np.matrix,matrix轉array用np.asarray或者matrix的A屬性

再看行向量或者列向量對應的array和matrix的實際維數

>>> a = np.array([1, 2, 3, 4, 5])
>>>> a
array([1, 2, 3, 4, 5])
>>> print(a.shape)  # 顯示爲1維,表示a是一維array
(5L,)
>>> b = np.array([[1, 2, 3, 4, 5]])  # 與b = a.reshape(1,5)等價
>>> print(b);print(b.shape)
[[1 2 3 4 5]]  # b是二維,shape=(1,5)
(1L, 5L)
>>> c = np.array([[1], [2], [3], [4], [5]])  # 與c = a.reshape(5,1)等價
>>> print(c);print(c.shape)  # c是二維,shape=(5,1)
[[1]   
 [2]
 [3]
 [4]
 [5]]
(5L, 1L)

再看看array的一維變多維,多維變一維。一維轉換爲多維用reshape

>>> a = np.arange(12)
>>> print(a);print(a.shape)
[ 0  1  2  3  4  5  6  7  8  9 10 11]
(12L,)

>>> b = a.reshape(3, 4);print(b);print(b.shape)  # 從一維變爲二維
[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]
(3L, 4L)

>>> c = a.reshape(2, 2, 3);print(c);print(c.shape)  # 從一維變成三維
[[[ 0  1  2]
  [ 3  4  5]]

 [[ 6  7  8]
  [ 9 10 11]]]
(2L, 2L, 3L)

>>> d = c.ravel();print(d);print(d.shape) # 多維轉一維,使用ravel函數,這個函數matrix也可以用,但是因爲matrix不管怎麼運算都是二維的(即shape數組長度爲2),所以matrix使用這個函數就是將二維矩陣M×N壓扁成一行形成1×K(K爲M和N的乘積)的二維矩陣
[ 0  1  2  3  4  5  6  7  8  9 10 11]
(12L,)

array中的很多函數(ufunc)運算都是元素級的,即函數針對array的每個元素進行處理,而matrix中的是根據矩陣的定義進行整體處理的

>>> a = np.array([1, 2, 3])
>>> b = np.array([4, 5, 6])
>>> c = a + b;print(c)  # 運算爲元素級
[5 7 9]
>>> d = a - b;print(d)  # 運算爲元素級
[-3 -3 -3]
>>> e = a * b;print(e)  # 運算爲元素級
[ 4 10 18]
>>> f = a**2;print(f)  # 運算爲元素級
[1 4 9]

如果想要array實現A和B矩陣式相乘,則要用np.dot(A,B)或者A.dot(B)
對於A和B都是一維的向量進行矩陣式相乘,最後得到的是一個數

>>> a = np.array([1, 2, 3])
>>> b = np.array([1, 2, 3])
>>> c = a.dot(b);print(c);print(c.shape);print(type(c))
14
()  # 由於最後結果是一個數值,不是array,自然沒有shape屬性了
<type 'numpy.int32'>
>>> d = b.dot(a);print(d)  # d與c完全一樣
14
#  這是二者都是一維的比較特殊的情況,如果A(m×n)或者B(p×q)大於一維,則np.dot(A,B)必須遵守矩陣乘法規則,即n必須與p相等
>>> a = np.array([[1, 2, 3], [1, 1, 1]]);b = np.array([1, 2, 3]);print(a.shape);
print(b.shape);c = a.dot(b);print(c);print(c.shape)
(2L, 3L)
(3L,)
[14  6]
(2L,)

>>> a = np.array([[1, 2, 3], [1, 1, 1]]);b = np.array([[1, 1], [2, 2] ,[3, 3]]);
print(a.shape);print(b.shape);c = a.dot(b);print(c);print(c.shape)
(2L, 3L)
(3L, 2L)
[[14 14]
 [ 6  6]]
(2L, 2L)

對於matrix的加減乘除,都是按照矩陣的定義進行的,當然運算結果都是二維的

>>> a = np.mat([[1, 2, 3], [4, 5, 6]]);print(a);print(a.shape)
[[1 2 3]
 [4 5 6]]
(2L, 3L)
>>> b = np.mat([[4, 5, 6], [7, 8, 9]]);print(b);print(b.shape)
[[4 5 6]
 [7 8 9]]
(2L, 3L)
>>> c = a + b;print(c);print(c.shape)  # 運算爲矩陣定義的加法
[[ 5  7  9]
 [11 13 15]]
(2L, 3L)
>>> c = a - b;print(c);print(c.shape)  # 運算爲矩陣定義的減法
[[-3 -3 -3]
 [-3 -3 -3]]
(2L, 3L)

>>> d = np.matrix([[1, 4], [2, 5], [3, 6]]);print(d);print(d.shape)
[[1 4]
 [2 5]
 [3 6]]
(3L, 2L)

>>> e = a * d;print(e);print(e.shape)  # 運算爲矩陣定義的乘法
[[14 32]
 [32 77]]
(2L, 2L)

>>> f = np.matrix([[1, 2], [3, 4]]);g = f**2;print(f);print(g)  # 運算爲矩陣乘法g = f * f
[[1 2]
 [3 4]]
[[ 7 10]
 [15 22]]

matrix應用ravel函數得到的仍然是matrix,形狀爲1×N

>>> print(g.ravel());print(g.shape)
[[ 7 10 15 22]]
(1L, 4L)

# 如果想得到一維的array,可以使用屬性A1
>>> i = g.A1;print(i);print(i.shape)
[ 7 10 15 22]
(4L,)

對於轉置,array和matrix都可以用transpose函數,matrix還可以直接使用T屬性

>>> a = np.arange(6).reshape(2, 3)
>>> a
array([[0, 1, 2],
       [3, 4, 5]])
>>> print(a.transpose())
[[0 3]
 [1 4]
 [2 5]]

>>> b = np.matrix(a)
>>> b
matrix([[0, 1, 2],
        [3, 4, 5]])
>>> b.transpose()
matrix([[0, 3],
        [1, 4],
        [2, 5]])

# 對於一維的array,談不上轉置,使用transpose函數後結果還是其自己
>>> a = np.array([1, 2, 3, 4]);print(a.shape)
(4L,)
>>> a
array([1, 2, 3, 4])
>>> b = a.transpose();print(b.shape)
(4L,)
>>> b
array([1, 2, 3, 4])

總結:一定要認識到matrix是二維的,一定要搞清楚你使用的array是幾維的,進行矩陣運算時,是否滿足矩陣運算的各維要求如果不滿足,應該如何快速度進行轉化

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章