师从清风
矩阵的重构和重新排列
reshape函数
reshape函数可以改变矩阵的形状,其常用语法为reshape(A,m,n)或者reshape(A,[m,n]),这可以将矩阵A的形状更改为m行n列,前提是转化前后的两个矩阵的元素总数要相同。例如有一个矩阵A,它原来的大小是2行6列,我们需要将其形状变成3行4列,那么,我们可以使用命令:reshape(A, 3, 4). (A和B中的元素个数是相同的)
从上面的运行结果可以看出,reshape函数实际上是按矩阵的线性索引来重新组织矩阵元素的。也就是说,它先取矩阵A的第一列,然后是第二列,依此类推,再按新的维度重新组织这些元素。因此,转换后的B矩阵中的元素和A矩阵中的元素是完全相同的,即A(:)和B(:)的结果完全相同。
若A是一个由12个元素组成的矩阵,命令reshape(A,3,[ ])、reshape(A,[ ],4)可以实reshape(A,3,4)一样的效果。
如果你给出的转换后的行数和列数的乘积不等于原始矩阵中元素的个数,那么MATLAB就会报错:
sort函数
sort函数用来对向量或者矩阵进行排序。如果是矩阵的话,可以对矩阵的每一行或每一列分别进行排序。
第一:对向量v排序
sort(v) 可以将向量v按照从小到大的顺序进行升序排列
sort(v,'descend')可以将向量v按照从大到小的顺序进行降序排列
注意,上面的用法我们只使用了sort函数的一个返回值,即排序后的向量;
事实上,sort函数可以有两个返回值,基本用法为:[sort_v , ind] = sort(v)
这里,sort_v是排序后的向量,ind是排序后的向量中的每个元素在v向量中的索引。
在上面的例子中,我们让sort函数返回了两个变量;sort_v和ind。它们是两个长度相等的向量,向量的方向和sort函数中输入的v向量的方向一致,都是行向量。向量v中所有元素的最小值为8,而8在v中的索引是4,因此sort_v中第一个元素为8,ind的第一个元素为4; 向量v中第二小的值为10,而10是v中的第1个元素,因此sort_v中第二个元素为10,ind的第二个元素为1;依次类推,可以得到sort_v和ind向量的值。事实上,这里有一个恒等关系成立:v(ind)运行的结果和sort_v的结果全一样,大家可以自行验证。
下面具体的应用场景
假设清风班上有10名同学,序号分别是1号、2号一直到10号。已知这10名同学的成绩构成的向量为:[84 70 61 90 69 78 88 74 92 76],问:清风班上哪三名同学的分数最高,分数分别是多少?
根据MATLAB返回的结果可以看出:9号、4号和7号这三名同学的分数排名前三,分别是92、90和88分。
引申一个问题:我们能不能知道这10名同学在班上的排名?
对矩阵A排序
使用方法:sort(A,dim)
dim = 1时,沿着行方向(从上至下)对矩阵的每一列按照从小到大的顺序分别进行排序
dim = 2时,沿着列方向(从左至右)对矩阵的每一行按照从小到大的顺序分别进行排序
注意:(1)当dim=1时,sort(A,1)可以直接写成sort(A);
(2)默认是升序排列的,我们可以在最后面加一个输入参数'descend',变成从大到小的降序排列;
(3)可以有两个返回值,代表的含义和对向量排序类似,表示排序后的元素在原矩阵所在行或所在列中的索引。
sort(A,2) % dim = 2时,沿着列方向(从左至右)对矩阵的每一行按照从小到大的顺序分别进行排序
sort(A,'descend') % 更改为降序排列
[sort_A , ind] = sort(A)
但这时候的A(ind)就不等于sort_A啦
sortrows函数
sortrows函数可以基于矩阵的某一列对矩阵进行排序。这个函数的用法较多,我们这里直接以一个具体的实例来讲解它的用法。
假设清风老师有6名学生,每一行代表一名学生。这六名同学的四门科目的成绩对应着四列,例如第一名同学的第一科成绩为95,第二科成绩为80,依次类推。
score = [95 80 85 79
95 67 78 90
95 67 78 75
95 67 64 73
86 85 82 84
86 87 84 88];
请解决下面的问题:
(1)请基于第一科的成绩按升序对这六名同学进行排序。当第一科成绩相同时,基于第二科成绩升序排列。如果第二科成绩还相同,就基于第三科成绩进行排序,依次类推。
sort_score1 = sortrows(score)
(2)请基于第一科的成绩按升序对这六名同学进行排序。当第一科成绩相同时,请保持其在矩阵中出现的先后顺序。
sort_score2 = sortrows(score,1)
(3)请基于第二科的成绩按升序对这六名同学进行排序。当第二科成绩相同时,请保持其在矩阵中出现的先后顺序。
sort_score3 = sortrows(score,2)
(4)请基于第一科的成绩按升序对这六名同学进行排序。当第一科成绩相同时,基于第三科成绩升序排列。如果第一科和第三科都相同,就保持在矩阵中出现的先后顺序。
sort_score4 = sortrows(score,[1,3])
事实上,sortrows(score)等价于sortrows(score, 1:size(score,2)),即sortrows(score, [1,2,3,4])
(5)请基于第一科的成绩对这六名同学进行降序排列。当第一科成绩相同时,基于第三科成绩降序排列。如果第一科和第三科都相同,就保持在矩阵中出现的先后顺序。
sort_score5 = sortrows(score,[1,3],'descend')
(6)请基于第一科的成绩对这六名同学进行降序排列。当第一科成绩相同时,基于第三科成绩升序排列。如果第一科和第三科都相同,就保持在矩阵中出现的先后顺序。
sort_score6 = sortrows(score,[1,3],{'descend','ascend'})
(7)请基于第一科的成绩按升序对这六名同学进行排序。当第一科成绩相同时,请保持其在矩阵中出现的先后顺序,并返回索引值。
score
[sort_score7 , ind7] = sortrows(score,1)
注意:score(ind7,:)得到的结果和sort_score7的结果完全一样。
score(ind7,:)
通过上面的例子可以看出,sortrows函数和sort函数的最大区别在于:
sort函数会对矩阵的每一列分别进行排序;
sortrows函数是基于某一列进行排序的,排序后得到的新矩阵的同一行元素不会改变。
score
sort(score)
sortrows(score)
在实际的应用场景中,sort函数一般只用于对向量进行排序;如果是矩阵或者表格排序,我们一般使用sortrows函数,例如Excel中对表格的排序就和sortrows函数类似。在以后的章节中,我们会专门讲到MATLAB中的表格数据,到时候还会用的这个函数。
(4)flip / fliplr / flipud函数
这三个函数用于对矩阵进行翻转
flip:翻转元素的顺序; fliplr:将数组从左向右翻转 ;flipud:将数组从上向下翻转
后面两个函数是flip函数的特例。
用法1: flip(A)
如果 A 为向量,flip(A) 将沿向量的长度方向翻转元素顺序。
如果 A 为矩阵,flip(A) 将反转每列元素的顺序。
A = [5 2 7 8 9]; % 行向量
flip(A)
等价于 A(end:-1:1)
A(end:-1:1)
B = [5;2;7;8;9]; % 列向量
flip(B)
C = [5 8 7;
4 2 6;
3 5 8;
6 4 1];
flip(C)
用法2: flip(A,dim)
flip(A,dim) 沿维度 dim 翻转 A 中元素的顺序。
如果 A 为矩阵,flip(A,1) 将沿着行方向对矩阵A上下翻转,
flip(A,2) 将沿着列方向对矩阵A左右翻转。
C = [5 8 7;
4 2 6;
3 5 8;
6 4 1];
flip(C,1) % 等价于flip(C) 或者 flipud(C)
flipud(C)
flip(C,2) % fliplr(C)
fliplr(C)
A = 1:5
flip(A)
flip(A,1)
(5)rot90函数
C = [5 8 7; 4 2 6; 3 5 8; 6 4 1]
rot90(C) % 逆时针方向旋转90度
rot90(C,2) % 逆时针方向旋转90*2=180度
rot90(C,3) % 逆时针方向旋转90*3=270度
rot90(C,-1) % 逆时针旋转-90度;等价于顺时针旋转90度
若有侵权,请联系作者