本文讲解下Matlab中的数组类型,Matlab中数组类型大约有以下几种:多维数组、元胞数组、字符与文本、结构体等。这篇可以算是MathWorks官方关于数组类型及用法中将的最详细的一篇了。文中,还涉及了函数的编辑与调用,值得学习一下。
多维数组
MATLAB®环境中的多维数组是具有多个下标的数组。创建多维数组的一种方法是调用具有多个参数的zeros
、ones
、rand
或randn
。例如,当然,可以在赋值语句后加;
取消输出。
>> R = randn(3,4,5)
R(:,:,1) =
-1.0891 1.1006 -1.4916 2.3505
0.0326 1.5442 -0.7423 -0.6156
0.5525 0.0859 -1.0616 0.7481
R(:,:,2) =
-0.1924 -1.4023 -0.1774 0.2916
0.8886 -1.4224 -0.1961 0.1978
-0.7648 0.4882 1.4193 1.5877
R(:,:,3) =
-0.8045 -0.2437 -1.1480 2.5855
0.6966 0.2157 0.1049 -0.6669
0.8351 -1.1658 0.7223 0.1873
R(:,:,4) =
-0.0825 -1.7947 0.1001 -0.6003
-1.9330 0.8404 -0.5445 0.4900
-0.4390 -0.8880 0.3035 0.7394
R(:,:,5) =
1.7119 -0.8396 0.9610 -1.9609
-0.1941 1.3546 0.1240 -0.1977
-2.1384 -1.0722 1.4367 -1.2078
如上,创建一个3×4×5数组,共包含3*4*5 = 60
个正态分布的随机元素。
三维数组可表示在矩形网格中采样的三维物理数据,例如室内温度。或者也可以表示矩阵序列 A(k) 或与时间相关的矩阵示例A(t)。在下面的示例中,第k个或第tk个矩阵的第(i, j)个元素由A(i,j,k)
表示。
MATLAB与丢勒的4阶幻方矩阵版本的区别在于交换了两个列。通过交换列,可以生成许多不同的幻方矩阵。语句如下:
p = perms(1:4);
生成 4! = 24 置换1:4
。第 k
个置换为行向量 p(k,:)
。然后,
A = magic(4);
M = zeros(4,4,24);
for k = 1:24
M(:,:,k) = A(:,p(k,:));
end
M的输出结果为:
>> M
M(:,:,1) =
13 3 2 16
8 10 11 5
12 6 7 9
1 15 14 4
M(:,:,2) =
13 3 16 2
8 10 5 11
12 6 9 7
1 15 4 14
M(:,:,3) =
13 2 3 16
8 11 10 5
12 7 6 9
1 14 15 4
M(:,:,4) =
13 2 16 3
8 11 5 10
12 7 9 6
1 14 4 15
M(:,:,5) =
13 16 3 2
8 5 10 11
12 9 6 7
1 4 15 14
M(:,:,6) =
13 16 2 3
8 5 11 10
12 9 7 6
1 4 14 15
M(:,:,7) =
3 13 2 16
10 8 11 5
6 12 7 9
15 1 14 4
M(:,:,8) =
3 13 16 2
10 8 5 11
6 12 9 7
15 1 4 14
M(:,:,9) =
3 2 13 16
10 11 8 5
6 7 12 9
15 14 1 4
M(:,:,10) =
3 2 16 13
10 11 5 8
6 7 9 12
15 14 4 1
M(:,:,11) =
3 16 13 2
10 5 8 11
6 9 12 7
15 4 1 14
M(:,:,12) =
3 16 2 13
10 5 11 8
6 9 7 12
15 4 14 1
M(:,:,13) =
2 13 3 16
11 8 10 5
7 12 6 9
14 1 15 4
M(:,:,14) =
2 13 16 3
11 8 5 10
7 12 9 6
14 1 4 15
M(:,:,15) =
2 3 13 16
11 10 8 5
7 6 12 9
14 15 1 4
M(:,:,16) =
2 3 16 13
11 10 5 8
7 6 9 12
14 15 4 1
M(:,:,17) =
2 16 13 3
11 5 8 10
7 9 12 6
14 4 1 15
M(:,:,18) =
2 16 3 13
11 5 10 8
7 9 6 12
14 4 15 1
M(:,:,19) =
16 13 3 2
5 8 10 11
9 12 6 7
4 1 15 14
M(:,:,20) =
16 13 2 3
5 8 11 10
9 12 7 6
4 1 14 15
M(:,:,21) =
16 3 13 2
5 10 8 11
9 6 12 7
4 15 1 14
M(:,:,22) =
16 3 2 13
5 10 11 8
9 6 7 12
4 15 14 1
M(:,:,23) =
16 2 13 3
5 11 8 10
9 7 12 6
4 14 1 15
M(:,:,24) =
16 2 3 13
5 11 10 8
9 7 6 12
4 14 15 1
将含有 24 个幻方矩阵的序列存储在三维数组 M
中。M
大小为
>> size(M)
ans =
4 4 24
注意
此插图中显示的矩阵顺序可能不同于您的结果。perms
函数始终返回输入向量的所有置换,但置换顺序可能因不同 MATLAB 版本而异。
语句sum(M,d)
,通过改变第 d
个下标来计算总和。因此是sum(M,1)
一个含有 24 个行向量副本的 1×4×24 数组;sum(M,2)
是一个含有 24 个列向量副本的 4×1×24 数组;sum(M,3)
在序列中添加 24 个矩阵。结果的大小为 4×4×1,因此它看似是 4×4 数组:
>> sum(M,1)
ans(:,:,1) =
34 34 34 34
ans(:,:,2) =
34 34 34 34
ans(:,:,3) =
34 34 34 34
ans(:,:,4) =
34 34 34 34
ans(:,:,5) =
34 34 34 34
ans(:,:,6) =
34 34 34 34
ans(:,:,7) =
34 34 34 34
ans(:,:,8) =
34 34 34 34
ans(:,:,9) =
34 34 34 34
ans(:,:,10) =
34 34 34 34
ans(:,:,11) =
34 34 34 34
ans(:,:,12) =
34 34 34 34
ans(:,:,13) =
34 34 34 34
ans(:,:,14) =
34 34 34 34
ans(:,:,15) =
34 34 34 34
ans(:,:,16) =
34 34 34 34
ans(:,:,17) =
34 34 34 34
ans(:,:,18) =
34 34 34 34
ans(:,:,19) =
34 34 34 34
ans(:,:,20) =
34 34 34 34
ans(:,:,21) =
34 34 34 34
ans(:,:,22) =
34 34 34 34
ans(:,:,23) =
34 34 34 34
ans(:,:,24) =
34 34 34 34
>> sum(M,2)
ans(:,:,1) =
34
34
34
34
ans(:,:,2) =
34
34
34
34
ans(:,:,3) =
34
34
34
34
ans(:,:,4) =
34
34
34
34
ans(:,:,5) =
34
34
34
34
ans(:,:,6) =
34
34
34
34
ans(:,:,7) =
34
34
34
34
ans(:,:,8) =
34
34
34
34
ans(:,:,9) =
34
34
34
34
ans(:,:,10) =
34
34
34
34
ans(:,:,11) =
34
34
34
34
ans(:,:,12) =
34
34
34
34
ans(:,:,13) =
34
34
34
34
ans(:,:,14) =
34
34
34
34
ans(:,:,15) =
34
34
34
34
ans(:,:,16) =
34
34
34
34
ans(:,:,17) =
34
34
34
34
ans(:,:,18) =
34
34
34
34
ans(:,:,19) =
34
34
34
34
ans(:,:,20) =
34
34
34
34
ans(:,:,21) =
34
34
34
34
ans(:,:,22) =
34
34
34
34
ans(:,:,23) =
34
34
34
34
ans(:,:,24) =
34
34
34
34
>> S = sum(M,3)
S =
204 204 204 204
204 204 204 204
204 204 204 204
204 204 204 204
元胞数组
MATLAB 中的元胞数组是以其他数组的副本为元素的多维数组。使用 cell
函数可以创建空矩阵的元胞数组。但是,更普遍的做法是,通过将其他内容的集合括入花括号 {}
中来创建元胞数组。花括号还可以与下标配合使用,以便访问各个元胞的内容。例如,
生成一个 1×3 元胞数组。这三个元胞包含幻方矩阵、列总和的行向量及其所有元素的乘积。当显示 C
时,您会看到
>> C = {A sum(A) prod(prod(A))}
C =
[4x4 double] [1x4 double] [2.0923e+13]
这是因为前两个元胞太大,无法在此有限空间中输出,但第三个元胞仅包含 16! 一个数字,因此有空间可以输出此数字。
请牢记以下两大要点。第一,要检索某个元胞的内容,请在花括号中使用下标。例如,C{1}
检索幻方矩阵,C{3}
为 16!。第二,元胞数组包含其他数组的副本,而不包含指向这些数组的指针。如果随后更改 A
,C
不会发生变化。
使用三维数组可以存储相同大小的矩阵序列。元胞数组可用于存储不同大小的矩阵序列。例如,
生成具有不同顺序的幻方矩阵序列:
>> M = cell(8,1);
>> for n = 1:8
M{n} = magic(n);
end
>> M
M =
[ 1]
[2x2 double]
[3x3 double]
[4x4 double]
[5x5 double]
[6x6 double]
[7x7 double]
[8x8 double]
使用以下命令可以检索 4×4 幻方矩阵
>> M{4}
ans =
16 2 3 13
5 11 10 8
9 7 6 12
4 14 15 1
字符与文本
使用单引号在 MATLAB 中输入文本。例如,
>> s = 'Hello'
s =
Hello
其结果与您目前已学过的数值矩阵或数组不属于同一类型,而是一个 1×5 字符数组。
字符在内部作为数字存储,而不会采用浮点格式存储。语句double(s)
将字符数组转换为数值矩阵,该矩阵包含每个字符的 ASCII 代码的浮点表示。结果为
>> a = double(s)
a =
72 101 108 108 111
语句char(a)
是刚才转换的逆转换。
>> s = char(a)
s =
Hello
将数字转换为字符可以调查计算机上的各种可用字体。基本 ASCII 字符集中的可打印字符由整数 32:127
表示。(小于 32 的整数表示不可打印的控制字符。)这些整数使用以下语句按相应的 6×16 数组的形式排列
F = reshape(32:127,16,6)';
扩展 ASCII 字符集中的可打印字符由 F+128
表示。将这些整数解释为字符时,结果取决于当前使用的字体。键入语句
>> char(F)
>> char(F+128)
ans =
!"#$%&'()*+,-./
0123456789:;<=>?
@ABCDEFGHIJKLMNO
PQRSTUVWXYZ[\]^_
`abcdefghijklmno
pqrstuvwxyz{|}~
ans =
¡¢£¤¥¦§¨©ª«¬®¯
°±²³´µ¶·¸¹º»¼½¾¿
ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏ
ÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞß
àáâãäåæçèéêëìíîï
ðñòóôõö÷øùúûüýþÿ
然后改变命令行窗口所用的字体。要更改字体,请在主页选项卡上的环境部分中,点击预设 > 字体。如果代码行中包含制表符,请使用等宽字体(例如,Monospaced
)以便在不同行中对齐制表符位置。
使用方括号进行串联可将文本变量联接到一起。如下语句,水平联接字符并生成:
>> h = [s, ' world']
h =
Hello world
如下语句,垂直联接字符并生成
>> v = [s; 'world']
v =
Hello
world
请注意,必须在 h
中的 'w'
前插入一个空格,并且 v
中的两个单词的长度必须相同。生成的数组均为字符数组;h
为 1×11,v
为 2×5。
要操作包含不同长度的行的文本主体,您有两种选择,即使用填充的字符数组或使用字符向量元胞数组。创建字符数组时,数组各行的长度必须相同。(使用空格填充较短行的末尾。)char
函数可执行这种填充操作。例如,生成一个 5×9 字符数组:
>> S = char('A','rolling','stone','gathers','momentum.')
S =
A
rolling
stone
gathers
momentum.
再者,您也可以将文本存储在元胞数组中。例如,创建一个不需要任何填充的 5×1 元胞数组,因为该数组的各行可以具有不同的长度:
>> C = {'A';'rolling';'stone';'gathers';'momentum.'}
C =
'A'
'rolling'
'stone'
'gathers'
'momentum.'
使用以下语句可以将填充后的字符数组转换为字符向量元胞数组:
>> C = cellstr(S)
C =
'A'
'rolling'
'stone'
'gathers'
'momentum.'
使用以下语句可以逆转此过程
>> S = char(C)
S =
A
rolling
stone
gathers
momentum.
结构体
结构体是多维 MATLAB 数组,包含可按文本字段标志符访问的元素。例如,创建一个具有三个字段的标量结构体:
>> S.name = 'Ed Plum';
>> S.score = 83;
>> S.grade = 'B+'
S =
name: 'Ed Plum'
score: 83
grade: 'B+'
与 MATLAB 环境中的所有其他内容一样,结构体也为数组,因此可以插入其他元素。在本示例中,数组的每个元素都是一个具有若干字段的结构体。可以一次添加一个字段,
S(2).name = 'Toni Miller';
S(2).score = 91;
S(2).grade = 'A-';
也可以使用一个语句添加整个元素:
>> S(3) = struct('name','Jerry Garcia',...
'score',70,'grade','C')
现在,结构体非常大以致仅输出摘要:
>> S
S =
1x3 struct array with fields:
name
score
grade
将不同字段重新组合为其他 MATLAB 数组的方法有许多种。这些方法大多基于逗号分隔列表的表示法。键入S.score
与键入S(1).score, S(2).score, S(3).score
相同,这是一个逗号分隔列表。
如果将生成此类列表的表达式括在方括号中,MATLAB 会将该列表中的每一项都存储在数组中。在本示例中,MATLAB 创建一个数值行向量,该向量包含结构体数组 S
的每个元素的 score
字段:
>> scores = [S.score]
scores =
83 91 70
>> avg_score = sum(scores)/length(scores)
avg_score =
81.3333
要根据某个文本字段(例如,name
)创建字符数组,请对 S.name
生成的逗号分隔列表调用 char
函数:
>> names = char(S.name)
names =
Ed Plum
Toni Miller
Jerry Garcia
同样,通过将生成列表的表达式括入花括号中,可以根据 name
字段创建元胞数组:
>> names = {S.name}
names =
'Ed Plum' 'Toni Miller' 'Jerry Garcia'
要将结构体数组的每个元素的字段赋值给结构体外部的单独变量,请指定等号左侧的每个输出,并将其全部括在方括号中:
>> [N1 N2 N3] = S.name
N1 =
Ed Plum
N2 =
Toni Miller
N3 =
Jerry Garcia
动态字段名称
访问结构体中的数据的最常用方法是指定要引用的字段的名称。访问结构体数据的另一种方法是使用动态字段名称。这些名称将字段表示为变量表达式,MATLAB 会在运行时计算这些表达式。此处显示的点-括号语法将 expression
作为动态字段名称:
structName.(expression)
使用标准 MATLAB 索引语法创建此字段的索引。例如,要在字段名称中计算 expression
,并在行 7
中的 1
至 25
列内获取该字段的值,请使用
structName.(expression)(7,1:25)
动态字段名称示例. 下面显示的 avgscore
函数可用于计算考试的平均分数,并使用动态字段名称检索 testscores
结构体中的信息:
function avg = avgscore(testscores, student, first, last)
for k = first:last
scores(k) = testscores.(student).week(k);
end
avg = sum(scores)/(last - first + 1);
您可以运行此函数,并对动态字段 student
使用不同值。首先,对包含 25 周内的分数的结构体进行初始化:
testscores.Ann_Lane.week(1:25) = ...
[95 89 76 82 79 92 94 92 89 81 75 93 ...
85 84 83 86 85 90 82 82 84 79 96 88 98];
testscores.William_King.week(1:25) = ...
[87 80 91 84 99 87 93 87 97 87 82 89 ...
86 82 90 98 75 79 92 84 90 93 84 78 81];
现在,运行 avgscore
,并在运行时使用动态字段名称为 testscores
结构体提供学生姓名字段:
>> avgscore(testscores, 'Ann_Lane', 7, 22)
ans =
85.2500
>> avgscore(testscores, 'William_King', 7, 22)
ans =
87.7500
以上这些代码的运行,需要先将函数部分保存为以函数名为名称的m文件,然后就可以直接通过函数调用了。详情如下图:
转载文章,原文出处:MathWorks官网,由古哥整理发布
如若转载,请注明出处:https://iymark.com/articles/3060.html