首页 > NumPy 阅读数:36

NumPy矩阵的创建和使用

NumPy 提供了两个基本的对象:一个多维数组(ndarray)对象和一个通用函数(ufunc)对象,其他对象都是在它们的基础上构建的。在 NumPy 中还包含两种基本的数据类型,即数组和矩阵。

NumPy 中的矩阵对象为 matrix,它包含有矩阵的数据处理、矩阵计算、转置、可逆性等功能。matrix 是 ndarray 的子类,矩阵对象是继承自 NumPy 数组对象的二维数组对象,因此,矩阵会含有数组的所有数据属性和方法。

但是,矩阵与数组还有一些重要的区别。

1) 矩阵对象可以使用一个 MATLAB 风格的字符串来创建,也就是一个以空格分隔列,以分号分隔行的字符串。

2) 矩阵是维数为2的特殊数组。矩阵的维数是固定的,即便是加减乘除各种运算,矩阵的维数不会发生变化,而数组在运算时其维数会发生变化。总之,矩阵的维数永远是二维的。

3) 矩阵与数组之间的转化,数组转矩阵用 numpy.asmatrix 或者 numpy.matrix,矩阵转数组用 numpy.asarray 或者 matrix 的 A 属性。

4) 数组中的很多通用函数(ufunc)运算都是元素级的,即函数是针对数组中的每个元素进行处理的,而矩阵是根据矩阵的定义进行整体处理的。

5) 矩阵默认的__array_priority__是 10.0,因而数组与矩阵对象混合的运算总是返回矩阵。

6) 矩阵有几个特有的属性使计算更加容易,这些属性如下:
  • .T:返回自身的转置;
  • .H:返回自身的共轭转置;
  • .I:返回自身的逆矩阵;
  • .A:返回自身数据的二维数组的一个视图(没有做任何的拷贝)。

矩阵对象(matrix)也可以使用其他的 matrix 对象、字符串或者其他的可以转换为一个 ndarray 的参数来构造。下面将介绍矩阵的创建、计算及操作。

1. 矩阵的创建

在 NumPy 中,使用 mat()、matrix() 以及 bmat() 函数创建矩阵的方法如下。

1) 使用字符串创建矩阵

在 mat() 函数中输入一个 MATLAB 风格的字符串,该字符串以空格分隔列,以分号分隔行。例如,numpy.mat('1 2 3;4 5 6;7 8 9'),可创建一个 3 行 3 列矩阵,矩阵中元素为整数。

2) 使用嵌套序列创建矩阵

在 mat() 函数中输入嵌套序列,例如,numpy.mat([[2,4,6,8],[1.0,3,5,7.0]]),可创建一个 2 行 4 列的矩阵,矩阵中的元素为浮点数。

3) 使用一个数组创建矩阵

在 mat() 函数中输入数组,例如 numpy.mat(numpy.arange(9).reshape(3,3)),可创建一个 3 行 3 列的矩阵,矩阵中的元素为整数。

4) 使用 matrix() 函数创建矩阵

matrix() 函数可以将字符串、嵌套序列、数组和 matrix 转换成矩阵,其函数格式如下:

matrix(data,dtype=None,copy=True)


其中,data 是指输入的用于转换为矩阵的数据。如果 dtype 是 None,那么数据类型将由 data 的内容来决定。如果 copy 为 True,则会复制 data 中的数据,否则会使用原来的数据缓冲。如果没有找到数据的缓冲区,当然也会进行数据复制。这说明用 matrix 函数创建矩阵,如果修改矩阵的值是不会改变输入 matrix 函数的 data 数据值。

注意:用 mat() 函数创建矩阵时,若输入 matrix 或 ndarray 对象,则不会为它们创建副本。也就是说用 mat() 函数创建矩阵时,如果修改矩阵的值,同时会改变输入 mat() 函数的 matrix 或 ndarray 的值。

5) 使用 bmat() 函数创建矩阵

如果想将小矩阵组合成大矩阵,在 NumPy 中,可以使用 bmat 分块(Block Matrix)矩阵函数实现,其函数格式如下:

bmat(obj,ldict=None,gdict=None)

其中,obj 为 matrix;ldict 和 gdict 为 None。

示例代码 example1 如下。
# -*- coding: utf-8 -*-
import numpy as np
#使用字符串创建矩阵
str = '1 2 3;4 5 6;7 8 9'
a = np.mat(str)
a[1,1]=11                           #修改a矩阵1行1列值,不会影响str
print ('用字符串创建矩阵:',a,str)      #观察str输出没有变化
#使用嵌套序列创建矩阵
b = np.mat( [[2,4,6,8],[1.0,3,5,7.0]])
print ('用嵌套序列创建矩阵:',b)
#使用一个数组创建矩阵
arr = np.arange(9).reshape(3,3)     #创建3行3列数组
c = np.mat(arr)
c[1,1] = 55                         #修改c矩阵1行1列值,arr值也跟着变化
print('数组创建矩阵:',c,arr)
#使用matrix函数创建矩阵
c = np.matrix(arr,dtype=np.float)   #用arr数组创建矩阵
c[1,1] = 66                         #修改c矩阵1行1列值,arr值不变化
d = np.matrix([[2,4,6,8],[1.0,3,5,7.0]],dtype=np.int64)  #用序列创建矩阵
e = np.matrix('1 2 3;4 5 6;7 8 9',dtype=np.str_)         #用字符串创建矩阵
f = np.matrix(a,dtype=np.str_)                           #用matrix对象创建矩阵
print('用matrix函数创建矩阵',c,arr, d, e,f)
#使用bmat函数创建矩阵
a=np.mat('3 3 3;4 4 4')
b=np.mat('1 1 1;2 2 2')
print ('用bmat函数创建矩阵:',np.bmat('a b; b a'))

2. 矩阵的计算及操作

在 NumPy 中,矩阵的计算是针对整个矩阵中的每个元素进行的,不需要使用 for 循环,而且运算效率更高。在进行矩阵的加、减、除法运算时,只有相同行数和列数的矩阵才能相互进行计算,否则会抛出程序异常。

矩阵的乘法计算有计算矢量积和计算数量积两种方式,如果计算矢量积,则运算符采用星号(*),并且星号左边矩阵的列数要与星号右边矩阵的行数相等,运算结果是矩阵中对应元素相乘的累加和。例如计算两矩阵 ma*mb,则运算结果矩阵 mc 为:

mc[0,0]=ma[0,0]*mb[0,0]+ma[0,1]*mb[1,0]+ma[0,2]*mb[2,0]+…+ma[0,n]*mb[n,0]
mc[0,1]=ma[0,0]*mb[0,1]+ma[0,1]*mb[1,1]+ma[0,2]*mb[2,1]…+ma[0,n]*mb[n,1]

mc[i,j]=ma[i,0]*mb[0,j]+ma[i,1]*mb[1,j]+ma[i,2]*mb[2,j]+…+ma[i,n]*mb[n,j]


如果计算数量积,也称为矩阵的点乘操作,则使用 multiply 函数。该函数是 NumPy 的通用函数,执行方法是将矩阵的对应元素相乘,与矢量积运算方式不同,类似于 MATLAB 中的点乘。

矩阵常用的操作有矩阵转置、索引取值、求矩阵的行列数、排序和将列表转换成矩阵等。矩阵计算和操作示例代码 example2 如下。
# -*- coding: utf-8 -*-
import numpy as np
#矩阵计算
ma = np.mat( [[6,4,2,8],[2.0,1,5,7.0]])        #创建2行4列矩阵
mb = np.mat(np.arange(9).reshape(3,3))         #创建3行3列矩阵
mc = np.mat(np.arange(8).reshape(2,4))         #创建2行4列矩阵
#print('矩阵相加:',ma+mb)            #不同行列数矩阵不能相加,会报错
print('矩阵相加:',ma+mc)             #相同行列数矩阵能相加
print('矩阵相减:',ma-mc)
print('矩阵相除:',mc/ma)
#矩阵相乘*,执行计算矩阵的矢量积操作
print('矩阵相乘:',ma,mc.T,ma*mc.T)    #mc.T为转置操作
#使用函数multiply, 执行计算矩阵数量积(点乘)操作
print('矩阵点乘:',np.multiply(ma,mc))
#矩阵操作
arr = np.array([[2,4,6,8],[1.0,3,5,7.0]])    #创建数组
print('取矩阵ma第1行值',ma[0])                 #取矩阵第1行值
ma[1,1]              #取矩阵第2行第2个数据
arr[1][1]            #数组取值,注意矩阵不能用ma[1][1]取值,会发生错误
ma.shape             #获得ma矩阵的行列数
ma.shape[0]          #获得ma矩阵的行数
ma.shape[1]          #获得ma矩阵的列数
#索引取值
ma[0,:]              #取得第1行的所有元素
print(ma[0,:])
ma[0,1:2]            #第1行第2个元素,注意左闭右开
print(ma[0,1:2])
ma.sort()            #对每1行进行排序
print(ma)
#将Python的列表转换成NumPy的矩阵
list=[1,2,3,5,6]
np.mat(list)         #列表转换成NumPy的矩阵
print(np.mat(list))