上一节中介绍了 MATLAB 中向量的基本操作,本节介绍 MATLAB 中矩阵的相关知识。 因为向量可以看成矩阵的一个特例,所以它们有许多类似的操作。

3.3.1 矩阵的创建方法

在 MATLAB 中, 矩阵的创建方法主要有三种, 分别是: 直接输入法、函数创建法和导入 本地文件中的数据。大家可以打开本节的配套代码:“code  3  3  1”进行学习。
 

1)直接输入法

我们先来看直接输入法,直接输入法适用于矩阵中元素数量较少的情况。
输入矩阵时要以中括号“[ ] ”作为标识符号, 矩阵的所有元素必须都在中括号内。矩阵 的同行元素之间用空格或逗号分隔, 行与行之间用分号或回车键分隔。
例如:命令 a = [1 2 3; 4 5 6];  可以在工作区创建出变量名为 a 的矩阵
notion image

2)函数创建法

MATLAB  提供了一些函数,这些函数可以用来生成某些特定的矩阵,我们这里介绍几组 最常用到的函数。
第一组函数:  zeros 、ones 和 eye 。这三个函数分别用来创建全为 0 的矩阵、全为 1 的矩 阵和单位矩阵。
以 zeros 函数为例, 其常见的用法有两种:(1)zeros(n)可以创建一个 n 行 n 列全为 0 的 矩阵;(2)zeros(m,n)可以创建一个 m 行 n 列全为 0 的矩阵。
例如:
notion image
ones 和 eye 的用法类似,大家可以看配套的讲解视频或者看 MATLAB 的帮助文档。
第二组函数: rand、randi 和 randn。这三个函数分别用来创建均匀分布的随机数、均匀 分布的随机整数和标准正态分布的随机数,以后会大量用到,请大家熟记。(数据的分布是概 率论里面的知识点,没学过的同学可以搜索关键词自学)
rand 函数用来创建区间 0 和 1 内均匀分布的随机数, 其最常用的方法有两种:(1)rand(n) 可以创建一个 n 行 n 列的随机数矩阵;(2)rand(m,n)可以创建一个 m 行 n 列的随机数矩阵。 由 rand 函数创建的随机数矩阵的每个元素都随机取样自 0 和 1 之间的均匀分布。
randi 函数 用来创建均匀分布的随机整数, 其最一般的用法为: randi([imin,imax],m,n), 该命令可创建一个 m 行 n 列的随机数矩阵,随机数矩阵中的每个元素都是从区间[imin,imax] 内随机抽取的整数。举个例子, 假设我们要模拟投掷 100 次骰子, 骰子有 6 个面, 那么我们可 以使用 randi([1,6],1,100)得到一个长度为 100 的行向量,向量中的每个元素都是取自 1,2,3,4,5,6 中的一个整数。另外, 如果 imin 等于 1,那么可以简写为 randi(imax,m,n);如 果 m 和 n 相同,即生成一个 n 行 n 列的方阵,那么可以直接写成 randi([imin,imax],n)。
randn 函数用来创建标准正态分布的随机数, 其使用方法和 rand 函数类似:(1)randn(n) 可以创建一个 n 行 n 列的随机数矩阵;(2)randn(m,n)可以创建一个 m 行 n 列的随机数矩阵。 由 randn 函数创建的随机数矩阵的每个元素都随机取样自标准正态分布。
注意: 因为我们生成的是随机数, 所以每次运行的结果可能会变化。除了上述这几个函数 外,MATLAB 还提供了其他一些与随机数生成相关的函数, 感兴趣的同学可以在 MATLAB 官网搜索关键词:随机数。
第三组函数: diag 和 blkdiag。
diag 函数可用来创建对角矩阵或者获取矩阵的对角元素
情况 1:如果输入的第一个参数是向量,则表示创建对角矩阵。
diag(v, k)  将向量 v 的元素放置在第 k 条对角线上,其他位置元素为 0。 k=0  表示主对角线, k>0  位于主对角线上方, k<0  位于主对角线下方。 如果 k=0,  可以直接写成 diag(v)。
notion image
情况 2:如果输入的第一个参数是矩阵,则表示获取矩阵的对角元素。
notion image
diag(A,k)  返回 A 的第 k 条对角线上元素的构成的列向量。
blkdiag 函数可用来创建分块对角矩阵。
分块对角矩阵是相对于常规的对角矩阵而言的,常规的对角矩阵沿对角线具有单个元素, 而分块对角矩阵的对角线的元素是矩阵。我们可采用以下形式表示一个分块对角矩阵:
notion image

3)导入本地文件中的数据

MATLAB 可读取本地的文件,支持的常见格式如下:
> .txt 、.dat  或 .csv  (适用于带分隔符的文本文件)
> .xls 、.xlsb 、.xlsm 、.xlsx 、.xltm 、.xltx  或 .ods(适用于电子表格文件)
由于这一块的内容比较丰富且可能涉及我们没学过的知识点, 所以会放在后面的章节进行 讲解。到时候我们会重点学习 MATLAB 菜单栏:“主页——导入数据”这个功能。

3.3.2 矩阵元素的引用

在讲解矩阵元素的引用之前,我们先来回顾一下矩阵的表示方式:
notion image
上方给出了一个m行n列的矩阵,对于第i行第j列的元素,我们用aij 表示。
因此, 我们可以使用矩阵元素所处的行(row)和列(column)来进行引用矩阵的某一个元素, 方式为: a(row_ind, column_ind).
这里的 row_ind 表示要引用的元素的行索引, column_ind 表示列索引。如果 row_ind 和 column_ind 都是一个常数,则表示提取矩阵中的单个元素;如果 row_ind 或 column_ind 是包 含有多个元素的向量, 则表示同时提取多个位置的元素。与向量类似, end 也可以用来替代最 后一个索引,通常和冒号法一起使用。
下面我们来举两个例子,大家也可以打开本节的配套代码学习:“code  3  3  2”。
notion image
前面我们学过, 可以使用 length 函数和 numel 函数来计算向量中包含的元素个数。那么, 怎样计算一个矩阵的大小呢?我们可以使用 size 函数,它有两种常见的用法:
(1)size(A)返回一个行向量,其元素是 A 的各维度的长度。若 A 是一个 3×4 的矩阵, 则 size(A)返回向量[3 4];如果让[r,c] = size(A),那么 r = 3,c = 4。
(2)size(A,dim)返回在维度 dim 上的长度。 dim = 1 时表示行; dim = 2 时表示列。若 A 是一个 3×4 的矩阵,则 size(A,1)返回 3,size(A,2)返回 4。
(length 函数和 numel 函数也可以用在矩阵上。 length 函数会返回行和列的较大值:对上 面的 A 矩阵, length(A)返回 4;numel 函数会返回矩阵中元素的总数, numel(A)  返回 12)
有时候我们需要取出矩阵的某一行或者某一列。以取出矩阵 A  的第一行为例,我们可以 使用代码 A(1,  1:end),即 row_ind 取 1 表示第一行, column_ind 取 1:end 表示从 1 到最后一列 的索引。这时候我们可以直接将其简写为: A(1, :),逗号后面是列索引的位置, 加一个冒号就 表示取出每一列的元素。同理,要取第一列的所有元素,我们可以使用代码: A(:, 1).
总结:
. A(:, n) 表示矩阵 A 的第 n 列的所有元素。
. A(m, :) 表示矩阵 A 的第 m 行的所有元素。
练习
notion image
 
前面我们介绍的是对矩阵的双下标进行索引, 即同时指定行索引和列索引, 中间用逗号隔 开。有同学会问, 我们能不能使用单个下标对矩阵进行索引呢?在 MATLAB 中是可以的,这 种单下标的索引方法称为线性索引
事实上, 在 MATLAB  中, 矩阵的数据在计算机的内存中被存储为单列。以下图为例, 下 面的矩阵虽然显示为 3×3  矩阵, 但 MATLAB 在内存中将它存储为单列,  由它的各列顺次连 接而成。例如,第 2 行第 2 列的元素的线性索引为 5,第 2 行第 3 列的元素的线性索引为 8。
notion image
 
我们可以利用线性索引来取出矩阵中的元素,尽管这种方式并不那么直观。
notion image
另外, A(: )命令可以将 A 中的所有元素按照线性索引的顺序重构成一个列向量
注:A(1:end)命令可以将 A 中的所有元素按照线性索引的顺序重构成一个行向
notion image
最后, sub2ind 和 ind2sub 函数可用于在矩阵的原始索引(双下标)和线性索引之间进行转 换。他们的功能刚好相反,sub2ind 将矩阵的下标转换为线性索引;ind2sub 将线性索引转换 为下标。
(1) ind = sub2ind(sz,row,col)  针对大小为 sz   的矩阵返回由 row  和 col  指定的行列下 标的对应线性索引 ind。此处, sz  是包含两个元素的向量, 其中 sz(1)  指定行数, sz(2)  指定列数。
(2) [row,col] = ind2sub(sz,ind)  返回数组 row  和 col,其中包含与大小为 sz   的矩阵的 线性索引 ind  对应的等效行和列下标。此处, sz  是包含两个元素的向量, 其中 sz(1)指定行数, sz(2)  指定列数。
我们举两个例子:
命令                               结果
ind = sub2ind([3,3],2,2)
5
ind = sub2ind([3,3],1,3)
7
[row,col] = ind2sub([3,3], 5)
row = 2    col = 2
[row,col] = ind2sub([3,3], 7)
row = 1    col = 3

3.3.3 矩阵元素的修改和删除

我们可以直接利用等号赋值的方法对矩阵中引用位置的元素进行修改, 用法和对向量元素 的修改类似。
notion image
当然,你也可以使用线性索引(单下标的索引)的方式对矩阵的元素进行修改:
notion image
注意, 如果你在赋值时将一个或多个元素置于矩阵现有的行和列索引的边界之外, 则会将 矩阵的大小进行拓展, MATLAB 会将没有赋值的位置的元素自动用 0 填充,使其保持为完整的矩形。
例如, A 是一个 2 行 3 列的矩阵,在 A 的第三行第四列的位置插入一个元素 88,矩阵 A 会自动进行拓展。
notion image
此外,我们还可以通过在现有索引范围之外插入一个新的矩阵来扩展原始矩阵的大小。
notion image
以上就是修改矩阵元素的方法,下面我们再来介绍删除矩阵元素的方法。
如果我们将等号右侧变成空向量[ ],则可以删除对应位置的元素。需要注意的是, 通常只 能删除矩阵的整行或者整列, 否则会报错。
请看下面的例子:
notion image
注意,也可以通过线性索引来删除矩阵的元素。使用线性索引删除后, MATLAB  会将矩 阵中剩下的元素按照线性索引的顺序放入到一个向量中。另外, 使用线性索引可以删除任意位 置的元素,不需要删除矩阵的一整行或者一整列。
notion image

3.3.4 矩阵的拼接和重复

有时候我们需要对多个矩阵进行拼接, 变成一个大的矩阵。根据矩阵拼接的方向, 我们可 以分为横向(水平)拼接和纵向(垂直)拼接,如下图所示:
notion image
横向拼接(horizontal catenate)
notion image
纵向拼接(vertical catenate)
如上图所示: 横向拼接要求矩阵的行数相同;纵向拼接要求矩阵的列数相同
在 MATLAB 中,我们可以使用命令[A, B]  或 [A   B]对矩阵 A 和 B 进行横向拼接,也可 以使用 MATLAB 中的内置函数: horzcat(A,B);类似的, 我们可以使用命令[A; B]对矩阵 A 和 B 进行纵向拼接,也可以使用 MATLAB 中的内置函数: vertcat(A,B)。
事实上, horzcat 和 vertcat 两个函数来源自 cat 函数, 这里的 cat 不是猫的意思, 而是单词 catenate 的缩写,可以翻译成连接。

cat 函数

命令 cat(dim,A,B)表示沿着维度 dim 方向将矩阵 B 拼接到矩阵 A 的末尾。
dim =  1  时表示沿着行方向从上往下进行拼接,即纵向拼接, 因此 cat(1,A,B)等价于 vertcat(A,B);
dim = 2  时表示沿着列方向从左自右进行拼接,即横向拼接, 因此 cat(2,A,B)等价于 horzcat(A,B)。
(horzcat 函数中的 horz 取自英文单词 horizontal,表示水平的意思; vertcat 函数中的 vert 取自英文单词 vertical,表示竖直的意思)
总结:若 A 和 B 的行数相同,那么使用[A, B] 、[A    B]、horzcat(A,B)以及 cat(2,A,B)都能 将 A 和 B横向拼接成一个大的矩阵; 若 A 和 B 的列数相同, 那么使用[A; B]、vertcat(A,B)以 及 cat(1,A,B)都能将 A 和 B 纵向拼接成一个大的矩阵。
下面举几个例子:
(1) 横向拼接的例子
notion image
(2) 纵向拼接的例子
notion image
(3) 拼接时维度不一致导致的报错
notion image
如果横向拼接时矩阵的行数不相同,或者纵向拼接矩阵的列数不相同,那么 MATLAB 就会报错。
注意,如果要拼接的矩阵的个数大于 2,也能使用上面的方法进行拼接, 请看下面的例子:
notion image
notion image

repmat函数

repmat(A,m,n)
除了对矩阵进行拼接外, 有时候我们需要对同一个矩阵进行重复的堆叠。如下图所示, 我 们将矩阵 A 重复堆叠 m ×n 次,得到一个新的矩阵:
notion image
在 MATLAB 中,对同一个矩阵进行重复的堆叠的代为 repmat(A,m,n)。
(如何记住 repmat 这个函数?    repeat 表示重复, matrix 表示矩阵) 我们举两个例子:
notion image
除了对整个矩阵进行重复的堆叠外,MATLAB 还可以对向量或者矩阵中的元素进行重复, 使用到的函数是 repelem 。(如何记住 repelem: repeat 重复 + element 元素)
repelem 函数有两种用法:

(1) 重复向量 v 中的元素:repelem(v, n)

当 n 为一个正整数时,表示把向量 v 中的每一个元素都重复 n 次; n 也可以为一个向量,其长度必须和 v 的长度相同,它可以将 v 中第 i 个位置的元素 v(i)重复 n(i) 次,其中 n(i)表示 n 中第 i 个位置的元素。
命令
结果
v = [5,3,8]; repelem(v, 2) %    将 v 中的每个元素都重复 2 次
5          5           3          3           8           8
repelem(v, [2,1,4]) %    将 v 中的第一个元素重复 2 次,第二个 元素重复 1 次,第三个元素重复 4 次
5        5       3  8        8       8       8

(2) 重复矩阵 A 中的元素:repelem(A,m,n)

m 和 n 分别表示沿着行方向(从上至下)以及沿着列方向(从左至右)将矩阵元素重复 的次数, 这里的 m 和 n 可以是正整数, 也可以是向量。如果 m 是向量,则 m 的长 度要和矩阵 A 的行数相同;如果 n 是向量,则 n 的长度要和矩阵 A 的列数相同。
notion image

3.3.5 矩阵的重构和重新排列

这一小节将介绍一些和矩阵的重构或重新排列相关的函数, 下表给出了本小节要学的函数 的名称和作用:
notion image

1reshape 函数

reshape 函数可以改变矩阵的形状,其常用语法为 reshape(A, m, n)或者 reshape(A,[m,n]), 这可以将矩阵 A 的形状更改为 m 行 n 列,前提是转换前后的两个矩阵的元素总数要相同。
例如有一个矩阵 A,它原来的形状是 2 行 6 列, 如果我们需要将其形状变成 3 行 4 列, 就 可以使用命令: reshape(A, 3, 4).
notion image
从上面的运行结果可以看出,reshape 函数实际上是按矩阵的线性索引来重新组织矩阵元 素的。也就是说, 它先取矩阵 A 的第一列, 然后是第二列, 依此类推, 再按新的维度重新组织 这些元素。因此,转换后的 B 矩阵中的元素和 A 矩阵中的元素是完全相同的,即 A(:)和 B(:) 的结果完全相同。
另外,我们不需要自己来计算转换后的矩阵有多少行或多少列。可以只给出转换后的行数, 列数用空向量[ ]代替; 或者只给出转换后的列数, 行数用空向量[ ]代替。MATLAB 会自动帮我 们计算转换后的矩阵大小。例如: 若 A 是一个由 12 个元素组成的矩阵, 命令 reshape(A,3,[ ]) 、 reshape(A,[ ],4)可以实现和 reshape(A,3,4)一样的效果。
如果你给出的转换后的行数和列数的乘积不等于原始矩阵中元素的个数,那么 MATLAB 就会报错:
命令
 结果
A = randi(10,3,6); B = reshape(A,5,8)
错误使用 reshape。元素数不能更改。请使用 [ ]  作为大小 输入之一,以自动计算该维度的适当大小。
A = randi(10,3,6); B = reshape(A,[ ],8)
错误使用 reshape 已知维度的乘积 8  不能被元素总数 18  整除。

2sort 函数

sort 函数是用于对向量或矩阵进行排序的。如果输入的参数是矩阵的话, 还可以对矩阵的 每一行或每一列分别进行排序。
①对向量排序
我们先来学习 sort 函数对向量排序,假设 v 是一个向量,有下面两种基础的用法:
> sort(v)  可以将向量 v 按照从小到大的顺序进行升序排列;
> sort(v, 'descend' )可以将向量 v 按照从大到小的顺序进行降序排列。
notion image
注意,上面的用法中, sort 函数只有一个返回值,即排序后的向量;事实上, sort 函数可 以有两个返回值,基本用法为:  [sort_v, ind] = sort(v)。这里, sort_v 是排序后的向 量,ind 是排序后的向量(即 sort_v)中的每个元素在原向量(即 v)中的索引(即下标、位置)。 我们来看一个具体的例子:
notion image
在上面的例子中,我们让 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],问:清风 班上哪三名同学的分数最高,分数分别是多少?
score = [84 70 61 90 69 78 88 74 92 76];  [sort_score, ind] = sort(score,'descend')
sort_score = [92 90 88 84 78 76 74 70 69 61] ind=[9   4   7    1   6   10   8  2   5  3]
根据 MATLAB 返回的结果可以看出: 9 号、4 号和 7 号这三名同学的分数排名前三, 分别 是 92 、90 和 88 分。
上面这个问题比较简单,我们再来提一个问题:我们能不能知道这 10 名同学在班上的排 名?例如: 1 号同学 84 分,在班上排名第 4;2 号同学 70 分,在班上排名第 8;3 号同学 61  分,排名第 10;4 号同学 90 分,排名第 2;…… ;依此类推,最终我们想要得到的排名为: [4 8 10 2 9 5 3 7 1 6].
大家观察 ind 的值和我们想得到的排名的值, 应该可以发现如下规律: 1 号同学排名第 4 , 而 ind 中等于 1 的元素的索引也为 4;2 号同学排名第 8,而 ind 中等于 2 的元素的索引也为 8;3 号同学排名第 10,而 ind 中等于 3 的元素的索引也为 10;4 号同学排名第 2,而 ind 中等 于 4 的元素的索引也为 2,依次类推,我们可以根据 ind 得到想要的排名。
根据上面的分析,我们可以将 ind  这个向量按照从小到大的顺序排列,排序后的向量是 [1,2,3, …,10],且排序后的向量中的每个元素在向量 ind 中的索引就是我们要得到的排名!
因此,我们只需要加下面这行代码, new_ind 就是我们想要计算的排名:
[sort_ind, new_ind] = sort(ind)
sort_ind = [1 2 3 4 5 6 7 8 9 10] new_ind = [4 8 10 2 9 5 3 7 1 6]
注意: 如果存在同学的成绩相同的情况, 那么这个代码就会存在问题, 要想解决这个问题 可以用到我们本章后面要学的 ismember 函数,这个问题也将放到本章最后的练习题中。
对矩阵排序
上面介绍的是 sort 函数对向量进行排序的应用,下面我们再来介绍 sort 函数对矩阵 A 进 行排序的用法: sort(A, dim).
> dim = 1 时,沿着行方向(从上至下)对矩阵的每一列升序排列
> dim = 2 时,沿着列方向(从左至右)对矩阵的每一行升序排列
注意:(1)当 dim=1 时, sort(A,1)可以直接写成 sort(A);(2)默认是升序排列的, 我们可 以在最后面加一个输入参数'descend',变成从大到小的降序排列;(3)可以有两个返回值,代 表的含义和对向量排序类似,表示排序后的元素在原矩阵所在行或所在列中的索引。
notion image

3sortrows 函数

sortrows  函数可以基于矩阵的某一列对矩阵进行排序,排序后得到的新矩阵的同一行元素不会改变。这个函数的用法较多,下面我们直接用一个具体的实例来讲解它的主要用法。
假设清风老师有 6 名学生, 下面这个矩阵保存着这六名同学在四门科目上的成绩。矩阵的 每一行代表一名学生。这六名同学的四门科目的成绩对应着四列, 例如第一名同学的第一科成绩为 95,第二科成绩为 80,依此类推。
notion image
请解决下面的问题:
(1) 请基于第一科的成绩按升序对这六名同学进行排序,得到排序后的成绩矩阵。若第 一科成绩相同, 则基于第二科成绩升序排列。如果第二科成绩还相同, 就基于第三 科成绩进行排序,依此类推。
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]; sort_score1 = sortrows(score)
86        85        82        84 86        87        84        88 95        67        64        73 95        67        78        75 95        67        78        90 95        80        85        79
(2) 请基于第一科的成绩按升序对这六名同学进行排序。当第一科成绩相同时, 请保持 其在矩阵中出现的先后顺序。
  sort_score2 = sortrows(score,1)
86        85        82        84 86        87        84        88 95        80        85        79 95        67        78        90 95        67        78        75 95        67        64        73
(3) 请基于第二科的成绩按升序对这六名同学进行排序。当第二科成绩相同时, 请保持 其在矩阵中出现的先后顺序。
  sort_score3 = sortrows(score,2)
95        67        78        90 95        67        78        75 95        67        64        73 95        80        85        79 86        85        82        84 86        87        84        88
(4) 请基于第一科的成绩按升序对这六名同学进行排序。当第一科成绩相同时, 基于第 三科成绩升序排列。如果第一科和第三科都相同, 就保持在矩阵中出现的先后顺序。
  sort_score4 = sortrows(score,[1,3])
86        85        82        84 86        87        84        88 95        67        64        73 95        67        78        90 95        67        78        75 95        80        85        79
事实上, sortrows(score)等价于 sortrows(score, 1:size(score,2)),即 sortrows(score, [1,2,3,4]).
(5) 请基于第一科的成绩对这六名同学进行降序排列。当第一科成绩相同时, 基于第三 科成绩降序排列。如果第一科和第三科都相同,就保持在矩阵中出现的先后顺序。
sort_score5 = sortrows(score,[1,3],'descend')
95        80        85        79 95        67        78        90 95        67        78        75 95        67        64        73 86        87        84        88 86        85        82        84
(6) 请基于第一科的成绩对这六名同学进行降序排列。当第一科成绩相同时, 基于第三 科成绩升序排列。如果第一科和第三科都相同,就保持在矩阵中出现的先后顺序。
sort_score6 = sortrows(score,[1,3],{'descend','ascend'}) %  使用元胞数组分别表示多个列的方向
95        67        64        73 95        67        78        90 95        67        78        75 95        80        85        79 86        85        82        84 86        87        84        88
(7) 请基于第一科的成绩按升序对这六名同学进行排序。当第一科成绩相同时, 请保持 其在矩阵中出现的先后顺序,并返回索引值。
        [sort_score7 , ind7] = sortrows(score,1)
sort_score7 = 86        85        82        84 86        87        84        88 95        80        85        79 95        67        78        90 95        67        78        75 95        67        64        73
ind7 = 5 6 1 2 3 4
ind7 的第一个元素为 5,这表示 sort_score7 的第一行元素 在原矩阵中位于第 5 行; ind7 的第二个元素为 6,这表示 sort_score7 的第二行元素在原矩阵中位于第 6 行;依次类 推,可以解释 ind7 每一个元素的含义。 因此 sort_score7 和 score(ind7, :)得到的结果完全相同。
通过上面的例子可以看出, sortrows 函数和 sort 函数的区别在于: sort 函数会对矩阵的每 一列分别进行排序; 而 sortrows 函数是基于某一列进行排序的, 排序后得到的新矩阵的同一行 元素不会改变。
notion image
在实际的应用场景中, sort 函数通常只用于对向量进行排序; 如果是对矩阵或者表格数据 进行排序,我们一般使用 sortrows 函数。如果大家熟悉 Excel 的话, 就会发现 Excel 中对数据 的排序就和 sortrows 函数类似。在以后的章节中,我们会专门讲解 MATLAB 中的表格数据类 型,到时候还会用到 sortrows 函数。
以下是 sortrows 函数的常用用法的总结:
(1) sortrows(A)基于矩阵 A  中第一列元素的值按升序对矩阵进行排序。当第一列包含重复值时,sortrows 会根据下一列中的值进行升序,并对后续的重复值重复此行为。 另外, sortrows(A)等价于 sortrows(A, 1:size(A,2)).
(2) sortrows(A,column)基于向量 column   中指定的列对矩阵 A  进行排序。例如, sortrows(A,2)会基于第二列中的元素按升序对矩阵 A 进行排序, 如果第二列中有相 同的元素, 则保持其在矩阵中出现的先后顺序。sortrows(A,[2 3])首先基于第二列中 的元素升序,若第二列元素相同,再基于第三列中的元素,对 A 矩阵进行升序排 序。如果第三列也出现数值相同的情况,就保持其在矩阵中出现的先后顺序。
(3) 排序时可以指定每一列的排序方向, sortrows(       ,direction)按 direction 指定的顺序 对 A 进行排序。direction 可以是'ascend'(默认值, 对于升序排序) 或 'descend'(对 于降序排序)。direction  也可以是元素为 'ascend'  和 'descend'   的元胞数组, 例如, sortrows(A,[1 3],{'ascend', 'descend'})  首先基于第一列按升序对 A 进行排序,如果 第一列中有数值相同,就基于第三列按降序排序。
(4) 除了返回排序后的矩阵,还可以返回排序后的各行在原矩阵中的位置索引。例如 [sorted_A, index] = sortrows(A, column),此时 A(index, :)的运行结果等于 sorted_A。

(4)flip / fliplr / flipud  函数

下面我们来学习 flip / fliplr / flipud 这三个函数,它们可以用来对向量或矩阵进行翻转操 作。其中, flip 函数是一个通用的翻转函数, 而 fliplr 和 flipud 是其特例, 分别用于从左到右和 从上到下的翻转。flip 翻译成中文是翻转,而 fliplr 函数可以拆解为 filp+  左边 left +  右边 right , flipud 则可以拆解为 flip +  上边 upper +  下边 down,大家可以根据英文来进行记忆。
flip 函数有两种用法:
用法 1: flip(A)
  • 如果 A 为向量, flip(A)  将翻转向量中各元素的顺序,向量的方向不变。
  • 如果 A  为矩阵, flip(A)  将对矩阵进行上下翻转。
命令                               结果
A = [5 2 7 8 9];    %  行向量 flip(A) %  等价于 A(end:-1:1)
9          8          7          2          5
A = [5;2;7;8;9];    %  列向量 flip(A)
9 8 7 2 5
A = [5 8 7; 4 2 6; 3 5 8; 6 4 1]; flip(A)    %  对矩阵进行上下翻转
6 4 1 3 5 8 4 2 6 5 8 7
用法 2: flip(A, dim)
flip(A,dim)  沿维度 dim  翻转 A  中元素的顺序。
  •  dim 为 1 时表示行,此时 flip(A,1)  将沿着行方向对矩阵 A 上下翻转。
  •  dim 为 2 时表示列,此时 flip(A,2)  将沿着列方向对矩阵 A 左右翻转。
命令                               
结果
A = [5 8 7; 4 2 6; 3 5 8; 6 4 1];
5 8 7 4 2 6 3 5 8 6 4 1
flip(A,1)    %  对矩阵进行上下翻转 %  等价于 flip(A)或者 flipud(A)
6 4 1 3 5 8 4 2 6 5 8 7
flip(A,2)    %  对矩阵进行左右翻转 %  等价于 fliplr(A)
7 8 5 6 2 4 8 5 3 1 4 6
请思考:若 A 是一个行向量, flip(A,1)返回的结果为什么还是 A?
答案:此时 A 被当成了一个一行的矩阵,对 A 进行上下翻转不会有变化。因此这提示我 们,要对向量进行翻转,直接使用 flip(A)即可。
flip 函数用法总结
(1) 若要对向量 A 中的元素进行翻转且向量的方向不变,那么可以直接使用 flip(A).
(2) 若要对矩阵 A 进行翻转, 那么 flip(A)、flip(A,1)和 flipud(A)都能对矩阵 A 进行上下 翻转; flip(A,2)和 fliplr(A)能对矩阵 A 进行左右翻转。
5rot90 函数
rot90 函数是对矩阵进行旋转的函数,它源于英文 rotate 一词,中文翻译为旋转。 rot90 函 数允许我们按 90 度或其倍数逆时针旋转矩阵。它的用法非常简单, rot90(A,k)将矩阵 A 按逆时 针方向旋转 k*90 度,其中 k 是一个整数;不提供 k 时 k 默认取 1。我们来看几个例子:
命令                               
结果
C = [5 8 7; 4 2 6; 3 5 8; 6 4 1];
5 8 7 4 2 6 3 5 8 6 4 1
rot90(C)    %  等价于 rot90(C,1)
rot90(C, 2)    % 逆时针旋转180°。
rot90(C, 3)    %逆时针旋转 270° 。 等价于顺时针旋转 90°
7 6 8 1 8 2 5 4 5 4 3 6
1 4 6 8 5 3 6 2 4 7 8 5
6 3 4 5 4 5 2 8 1 8 6 7
 

Loading...
公告
🎉大学生科技协会(2024)网站试运行🎉
-- 感谢您的支持 --- 科协获:
小平科技创新团队 (青少年科技创新领域国家级最高荣誉,全校唯一)
全国高校百强社团 中国大学生ican物联网创新创业实践教育基地 校十佳社团 “一院一品”智能空间 科技竞赛优秀组织单位
阅读科协简介了解更多吧!