原文
这里给出一些简单处理矩阵的题目,然后给出两种语言的代码,可以对比两种代码的风格。
文章练习分为两部分,第一部分是常见各种对矩阵地操作,第二部分正在完善。
注:部分取自Numpy100题,目前在45题左右,现在打算整理文章内容
准备
(1)Python是开源的,可以在Python官网免费下载,最好再下载Anaconda配套使用,可以在清华大学开源镜像站下载;
(2)Matlab需要付费获得账号,如果有账号但没有安装,可以使用网页版MATLAB Online R2020a;在MathWorks下载正版软件;也可以用开源软件Octave替代(至少本文内容可以),Octave官网下载;;
(3)Matlab安装基础版本即可,Octave直接安装;
(4) Python需要安装numpy库,参考Numpy库的下载及安装(吐血总结)_WoLykos-CSDN博客_numpy库;
(5) Matlab、Octave使用
(6)Python使用
一、练习
第一部分
(1)创建向量;向量排序;向量的最大值、最小值、平均值、标准差;将向量中的最大值替换为0;对向量(数组)对大于3小于8的元素取负;
(2)创建矩阵(数组)
(3)向量转化为矩阵、矩阵转化为向量;
(4)获取矩阵(向量、数组)的属性:大小、行数、列数、维度、类型等;
(5)子矩阵提取:行、列、某几行几列等;
(6)
(7)删除矩阵
(8)矩阵(向量)的基本运算:加、减、乘、求逆、幂次等;
(9)矩阵(向量)的基本变换:转置、翻转;
第二部分
二、解答
注:Python没有经过np.mat的都是数组,本文前半部分使用了np.mat将数组转化为矩阵,后半部分发现太麻烦省略了这一步。
0、准备
Matlab、Octave不需要操作,Python需要
#本文采用
>>>import numpy as np
#也可使用,这不需要写np.
>>>from numpy import *
第一部分
(1)创建向量;向量排序;向量的最大值、最小值、平均值、标准差;将向量中的最大值替换为0;对向量(数组)对大于3小于8的元素取负;
Python
#创建向量,以从1到49的整数向量为例
>>>vec=np.arange(10,50)
>>>vec=np.linspace(1,49,49)
#向量排序
>>>temp=np.random.random(10)
>>>temp.sort() #从小到大
#向量的最大值、最小值、平均值、标准差
>>>Max,Min,Mean,Std=vec.max(),vec.min(),vec.mean(),vec.std()
#将向量的最大值替换为0
>>>temp2=np.random.random(10)
>>>temp2[temp2.argmax()]=0
#将向量重大于3小于8的元素取负
>>>temp=10*np.random.random(10)
>>>temp[(3<temp)&(temp<8)]*=-1
Matlab
%创建向量,以从1到49的整数向量为例
>>vec=10:1:49
>>linspace(1,49,49)
%向量排序
>>sort(vec) %从小到大
%向量中的最大值、最小值、平均值、标准差
>>temp=10*rand(10,1)
>>Max=max(temp)
>>Min=min(temp)
>>Mean=mean(temp)
>>Std=std(temp)
%将向量中的最大值替换为0
>>[max,index]=max(temp)
>>temp(index)=0
%将向量重大于3小于8的元素取负
>>temp(find((temp>3)&(temp<8)))=-1*temp(find((temp>3)&(temp<8)))
(2)创建矩阵(数组)
Python
#创建矩阵
>>>a=[[1,2],[3,4],[5,6]] #类型为'list'
>>>A=np.array([[1,2],[3,4],[5,6]]) #类型为'numpy.ndarray'
>>>A=np.mat([[1,2],[3,4],[5,6]]) #类型为'numpy.matrix'
>>>A=np.mat(1+np.arange(6).reshape(3,2))
>>>A=np.mat(1+np.arange(6,dtype='double').reshape(3,2)) #感谢 @六道木 指出
>>>A=np.mat(np.arange(1,7).reshape(3,2)) #快速方法,注意arange不包括最后一项,单参数从0开始
#创建复数矩阵
>>>A=np.mat([[1+1j,2+1j]]) #只能用j,并且j前面要有数字
#特殊矩阵,直接np.zeros获得的类型为'numpy.ndarray'
>>>np.mat(np.zeros(3)) #1×3零矩阵
>>>np.mat(np.zeros((3,4))) #3×4零矩阵
>>>np.mat(np.ones(3)) #1×3一矩阵
>>>np.mat(np.ones((3,4))) #3×4一矩阵
>>>np.mat(np.eye(3)) #3×3单位阵
>>>np.mat(np.eye(3,4)) #不知如何描述,注意这里少一层括号,感谢 @六道木 指出
>>>np.mat(np.identity(3)) #3×3单位阵,identity只能是方阵,没有eye灵活(还可以调整对角线位置)
>>>np.mat(np.random.random(3)) #3×1随机数矩阵
>>>np.mat(np.random.random((3,3,3))) #3×3×3随机数数组,random.random产生的随机数在(0,1)
#对角阵
>>>np.mat(np.diag([1,2,3]))
>>>np.mat(np.diag([1,2,3],1)) #上移一格的对角阵
#矩阵的最大值、最小值、平均值、标准差
>>>Max,Min,Mean,Std=A.max(),A.min(),A.mean(),A.std()
#将矩阵的最大值替换为0
>>>temp2=np.random.random(10)
>>>temp2[temp2.argmax()]=0
#对大于3小于8的元素取负
#这里的对象是数组,可通过np.mat()转化为矩阵
>>>temp=10*np.random.random(10).reshape(2,5)
>>>temp[(3<temp)&(temp<8)]*=-1
Matlab
%创建矩阵
>>A=[1,2;3,4;5,6]
>>A=reshape(1:1:6,2,3)' %快速方法,注意这里要转置
%创建复数矩阵
>>A=[1+i,2+2i]
>>A=[1+j,2+2j] %i和j都可以使用,i和j前面都要有数字
%常用矩阵
>>zeros(3) %3×3零矩阵
>>zeros(3,4) %3×4零矩阵
>>ones(3) %3×3一矩阵
>>ones(3,4) %3×4一矩阵
>>eye(3) %3×3的单位阵
>>eye(3,4) %不知如何描述
>>rand %(0,1)均匀分布随机数
>>rand(3) %3×3取值(0,1)随机数阵
>>rand(3,4) %3×4取值(0,1)随机数阵
>>randn %(0,1)标准正态分布随机数
>>randn(3) %3×3标准正态分布随机数阵
>>randn(3,4) %3×4标准正态分布随机数阵
>>magic(3) %3阶魔方阵
>>vander([1,2,3]) %范得蒙矩阵(Vandermonde)
>>hilb(3) %3阶希尔伯特矩阵
>>invhilb(3) %3阶希尔伯特矩阵的逆矩阵
>>toeplitz([1,2,3])
>>toeplitz([1,2,3],[1,5]) %托普利兹矩阵(Toeplitz)
>>compan([1,2,3]) %友阵,不是伴随矩阵
>>pascal(3) %3阶帕斯卡矩阵
%对角阵
>>diag([1,2,3])
>>diag([1,2,3],1) %上移一格的对角阵
%矩阵中的最大值、最小值、平均值、标准差
>>temp=10*rand(3,3)
>>Max=max(temp)
>>Min=min(temp)
>>Mean=mean(temp)
>>Std=std(temp)
%将矩阵中的最大值替换为0
>>temp(find(temp==max(max(temp))))=0
%将矩阵重大于3小于8的元素取负
>>temp(find((temp>3)&(temp<8)))=-1*temp(find((temp>3)&(temp<8)))
(3)向量转化为矩阵、矩阵转化为向量;
Python
#向量转化为矩阵
>>>A=np.mat(1+np.arange(6).reshape(3,2))
#矩阵转化为向量
>>>np.ravel(A) #返回视图
>>>A.flatten() #返回拷贝
>>>A.reshape(-1)
Matlab
#Matlab的reshape为列优先
#将向量转化为矩阵
>>temp=[1,2,3,4,5,6];
>>temp2=reshape(temp,2,3)'
#将矩阵转化为向量
>>reshape(temp2',1,numel(temp2))
(4)获取矩阵(向量、数组)的属性:大小、行数、列数、维度、类型等;
Python:
#类型
>>>type(A)
#大小
>>>A.shape
>>>np.shape(A)
#行数
>>>A.shape[0]
>>>np.shape(A)[0] #shape的第一个数字
>>>len(A)
#列数
>>>A.shape[1]
>>>np.shape(A)[1] #shape的第二个数字
#维数(秩)
>>>A.ndim
>>>np.ndim(A)
#元素个数
>>>A.size
>>>np.size(A)
#元素类型
>>>A.dtype
#元素字节大小
>>>A.itemsize
Matlab:
%类型:矩阵
%大小
>>size(A)
%行数
>>size(A,1)
%列数
>>size(A,2)
%维数
>>rank(A)
%元素个数
>>numel(A) %可以获得图像的像素个数
%元素类型
>>class(A)
>>whos A
%元素字节大小*************************************************************
>>
%矩阵非0元的分布
>>spy(A)
%矩阵的特征值、特征向量(必须为方阵)
>>E=eig(temp)
>>[V,D]=eig(temp) %经过了相似变换
>>[V,D]=eig(temp,'nobalance') %直接求
(5)获取矩阵(向量、数组)的切片:行、列、某几行几列、中心矩阵等;
Python
#第1行第1列
>>>A[0,0]
#第1列
>>>A[:,0]
#第1行
>>>A[0]
>>>A[0,:]
#第1行+第3行第1列子矩阵
>>>A[[0,2],0]
#除边界的子矩阵
>>>A[1:-1,1:-1]
#修改数值:A[i-1,j-1]=c
Matlab
%统一表达式:矩阵([提取的行构成的向量],[提取的列构成的向量])
>>temp=rand(3,4)
%第1行第1列
>>temp(1,1)
%第1列
>>temp(:,1)
%第1行
>>temp(1,:)
%第1行第3行第1列子矩阵
>>temp([1,3],1)
>>temp([1,3],[1])
%除边界的子矩阵
>>temp(2:(size(temp,1)-1),2:(size(temp,2)-1)) %没有看到相关函数
%另外还可以通过索引向量获取元素,按列从小到大、行从小到大,如
>>temp([2,1,4,7])
%修改数值:A(i,j)=c
(6)
Python
#右边添加矩阵,多种方法
>>>np.c_[A,[[7],[8],[9]]] #c理解为将矩阵排成一行
>>>np.column_stack((A,[[7],[8],[9]]))
>>>np.hstack((A,[[7],[8],[9]])) #水平拼接
>>>np.insert(A,2,values=[[7,8,9]],axis=1) #axis=1表示添加列,values=转置了,第二个参数表示合并后所在列数
>>>np.concatenate((A,[[7],[8],[9]]),axis=1) #axis=1表示添加列
>>>np.append(A,[[7],[8],[9]],axis=1) #axis=1表示添加列
#下边添加矩阵,多种方法
>>>np.r_[A,[[7,8],[9,10]]] #r理解为将矩阵排成一列
>>>np.row_stack((A,[[7,8],[9,10]]))
>>>np.vstack((A,[[7,8],[9,10]])) #垂直拼接
>>>np.insert(A,3,values=[[7,8],[9,10]],axis=0) #axis=0表示添加行,values=没有改变,第二个参数表示合并后所在行数
>>>np.concatenate((A,[[7,8],[9,10]]))
>>>np.concatenate((A,[[7,8],[9,10]]),axis=0) #axis=0表示添加行
>>>np.append(A,[[7,8],[9,10]],axis=0) #axis=0表示添加行
#周围添加一圈0
>>>np.pad(A,pad_width=1,mode='constant',constant_values=0)
#此外还有stack、dstack增加维度
Matlab
%右边添加矩阵
>>[A,[7;8;9]]
%下边添加矩阵
>>[A;[7,8;9,10]]
%在矩阵周围添一圈0
%没有找到相应代码,有人说padarray,但是用不了;构造一个新矩阵可以朴素地实现
(7)删除矩阵
Python
#删除第1行
>>>np.delete(A,0,axis=0)
#删除第1行和第3行
>>>np.delete(A,[0,2],axis=0)
#删除第1列
>>>np.delete(A,1,axis=1)
Matlab
%删除第1行
>>A(1,:)=[]
%删除第1行和第3行
>>A([1,3],:)=[]
%删除第1列
>>A(:,1)=[]
(8)矩阵的基本运算:加减、乘、求逆(除法)、幂次等;
此处取
Python
#加减
>>>B+C #矩阵加减法
>>>1+B #标量加减法
#乘法
>>>2*B #标量乘法
>>>np.dot(B,C) #矩阵乘法
>>>B@C #矩阵乘法
>>>B*C #仅B,C为矩阵时为矩阵乘法,若B,C为数组则为点乘
>>>np.multiply(B,C) #矩阵点乘(Hadamard乘积)
#求逆
>>>B.I
Matlab
%加减
>>B+C %矩阵加减法
>>1+B %标量加减法
%乘法
>>B*C %矩阵乘法
>>2*B %标量乘法
>>B.*C %矩阵点乘(Hadamard乘积)
%求逆
>>inv(B)
>>pinv(B) %广义逆矩阵
>>AB %矩阵左除
>>B/A %矩阵右除
%乘方,点幂
>>B^3 %B的3次方
>>B.^3
%行列式
>>det(B)
%矩阵的迹
trace(B)
(9)矩阵的基本变换:转置、翻转;
Python
#转置
>>>B.T #自身转置
>>>B.H #Hermite转置
#反转向量
>>>vec[::-1]
Matlab
%转置
>>B.' %矩阵转置
>>B' %Hermite转置,实矩阵不影响效果
%翻转
>>vec(end:-1:1) %翻转向量
>>fliplr(B) %左右翻转
>>flipud(B) %上下翻转
>>rot90(B) %逆时针旋转90°
>>rot90(A,k) %逆时针旋转k×90°
第2部分
(1)获取向量中非0元素的索引;
Python
>>>np.nonzero([1,2,0,0,4,0])
Matlab
%最简
>>find([1,2,0,0,4,0])
%前2个
>>find([1,2,0,0,4,0],2)
%后2个,最后一个参数默认为'first'
>>find([1,2,0,0,4,0],2,'last')
%行标和列标
>>[row,col]=>>find([1,2,0,0,4,0])
%行标、列标和非零向量
>>[row,col,v]=>>find([1,2,0,0,4,0])
(2)创建特殊矩阵:
Python
#方法一
>>>temp=np.zeros((8,8),dtype=int)
>>>temp[1::2,::2] = 1
>>>temp[::2,1::2] = 1 #seq[start:end:step]
#方法二
>>>np.tile( np.array([[0,1],[1,0]]), (4,4))
Matlab
>>temp=zeros(8)
>>temp(1:2:end,2:2:end)=1
>>temp(2:2:end,1:2:end)=1
(4)找到两个矩阵(数组)的共同元素
Python
#intersect1d:Return the sorted, unique values that are in both of the input arrays
temp1=np.random.randint(0,10,10)
temp2=np.random.randint(0,10,10)
np.intersect1d(temp1,temp2)
Matlab
(5)矩阵(数组)取整
Python
#多种方法,这里可以通过查看元素类型
temp=10*np.random.random(10).reshape(2,5)
temp-temp%1 #减去小数
np.floor(temp) #下取整
np.ceil(temp)-1 #上取整减1
temp.astype(int) #仅该式转化为整型
np.trunc(temp)
Matlab
floor() %-∞方向取整
ceil() %+∞方向取整
round() %四舍五入
fix() %0方向取整
(6)创建一个5x5的矩阵,其中每行的数值范围从0到4;
Python
#一种方法,可用来逐行增加
>>>temp=np.zeros((5,5))
>>>temp+=np.arange(5)
Matlab
(7)对矩阵(数组)求和;
Python
>>>temp=np.arange(10)
>>>sum(temp) #方法一
>>>np.add.reduce(temp) #方法二,听说更快
Matlab
>>sum(temp) %对列求和或对向量求和
(8)对于两个随机数组A和B,检查它们是否相等;
Python
#数组要有相同的shape并且可以比较
#方法一
>>>A = np.random.randint(0,2,5)
>>>B = np.random.randint(0,2,5)
>>>equal = np.allclose(A,B)
>>>print(equal)
#方法二
>>>equal = np.array_equal(A,B)
>>>print(equal)
Matlab
(9)创建一个只读数组;
Python
>>>Z=np.zeros(10)
>>>Z.flags.writeable=False
Matalb
(10)将笛卡尔坐标下的一个10x2的矩阵转换为极坐标形式;
Python(直接挪用了)
>>>Z = np.random.random((10,2))
>>>X,Y = Z[:,0], Z[:,1]
>>>R = np.sqrt(X**2+Y**2)
>>>T = np.arctan2(Y,X)
Matlab
>>Z=rand(10,2);X=Z(:,1);Y=Z(:,2);
>>R=sqrt(X.*X+Y.*Y);T=atan2(Y,X)
(11)
参考文章
在写的时候看到的,有一定关联没看太懂的,不一定有用,留作以后参考
1、python的常见矩阵运算
2、灵魂歌手水云天:MATLAB数据类型及相互转换(一)
3、Numpy中的数组拼接、合并操作(concatenate, append, stack, hstack, vstack, r_, c_等)
4、Numpy中stack(),hstack(),vstack()函数详解_张康的博客-CSDN博客_vstack函数
5、matlab中矩阵的表示与简单操作 - Jaoany - 博客园