numpy 矩阵乘法、点乘、转置(array 和 matrix)

转载自 https://blog.csdn.net/whgyxy/article/details/53930031
好文,帮你梳理清楚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)

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

再看看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,)

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

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]
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

如果想要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)

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

对于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]]
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

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,)
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

对于转置,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])
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

总结:一定要认识到matrix是二维的,一定要搞清楚你使用的array是几维的,进行矩阵运算时,是否满足矩阵运算的各维要求如果不满足,应该如何快速度进行转化

发布了4 篇原创文章 · 获赞 1 · 访问量 7637

Numpy中两大重要类型array类型(N维数组ndarray)和矩阵类型matrix是很多基于Numpy数值计算的基础,因此搞清楚两者的关系是相当重要的, 特别是程序中混杂了这两种类型,还夹带着一些加减乘除的运算,那简直有一种剪不断理还乱的感觉,时不时脑袋就飞出一句话:尼玛,程序又不听话了!

猜你喜欢

转载自blog.csdn.net/qq_31274209/article/details/81117627