学习一门技术最好的方式就是阅读官方文档,可以查看MATLAB官方文档
string, structure, cell,Scalar
字符串,结构,单元格,标量
数据类型
MATLAB中主要的数据类型如下:
下面依次介绍各种主要的数据类型:
数值类型(numeric)
*在MATLAB中,数值类型的变量被默认为double类型的,可以使用类型转换将其转换
n = 3;
class(n) % 得到 double
n = int8(3);
class(n) % 得到 int8
为其他数值类型.
MATLAB支持的数值类型见下表:
数值类型 | 描述 |
---|---|
double | 双精度浮点数 |
single | 单精度浮点数 |
int8 | 8位带符号整数 |
int16 | 16位带符号整数 |
int32 | 32位带符号整数 |
int64 | 64位带符号整数 |
uint8 | 8位无符号整数,u指unsign无符号 |
uint16 | 16位无符号整数 |
uint32 | 32位无符号整数 |
uint64 | 64位无符号整数 |
字符类型(char)
- 在MATLAB中,字符串类型由一对单引号 ‘ ‘包裹一段文字来定义.标准ASCII字符可以被转换为对应的 ASCII码.
*在MATLAB中默认使用Unicode编码 一个字符char占用两个字节
s1 = 'h';
whos
uint16(s1) % 得到 104
字符串类型(String)
- 字符串在内存中是以字符矩阵的形式存储的,可以对其进行矩阵的索引以及赋值操作:
```matlab str1 = ‘hello’; str2 = ‘world’;
str3 = [str1 str2]; size(str3) % 得到 [1✖10]
str4 = [str1; str2]; size(str4) % 得到 [2✖5]
str3
str3 =
'helloworld'
str4
str4 =
2×5 char 数组
'hello'
'world'
```matlab
str = 'aardvark';
'a' == str % 得到 [1 1 0 0 0 1 0 0]
str(str == 'a') = 'Z' % 得到 'ZZrdvZrk'
关于双引号String型和单引号Char型
str1 = 'hello'; str2 = "hello"; whos %输出 % Name Size Bytes Class Attributes 属性 % str1 1x5 10 char % str2 1x1 150 string
逻辑运算符
许多数学和逻辑运算符可以应用于字符串 ```matlab str = ‘aardvark’; ‘a’ == str %%输出 % ans =
% 1×8 logical 数组
% 1 1 0 0 0 1 0 0 是逻辑变量,不是数值变量
```matlab
str(str == 'a') = 'Z'
%% 输出
% str =
% 'ZZrdvZrk'
%因为str == 'a'输出结果为逻辑变量,MTATLAB会认为'1'执行,'0'不执行,如果要通过索引来达到相同的目的,str([1 2 6])='Z'
结构体(structure)
在MATLAB中,结构体是一个存储{键: 值}的数据结构,类似于Python语言中的字典.
struct 结构体数组
结构体的基本使用
用 . 访问字段
与大多数编程语言类似,MATLAB使用 字符. 来访问结构体中的字段:
student.name = 'John Doe';
student.id = 'jdo2@sfu.ca';
student.number = 301073268;
student.grade = [100, 75, 73; ...
95, 91, 85.5; ...
100, 98, 72];
student
扩充或缩减列表
对结构体列表使用下标表达式可以扩充或缩减结构体列表
student(2).name = 'Ann Lane';
student(2).id = 'aln4@sfu.ca';
student(2).number = 301078853;
student(2).grade = [95 100 90; 95 82 97; 100 85 100];
student
student(1) = [] % 删除student列表第一项
>>student
student =
包含以下字段的 1×2 struct 数组:
name
id
number
grade
>> fieldnames(student)
ans =
4×1 cell 数组
{'name' }
{'id' }
{'number'}
{'grade' }
>> rmfield(student,'id')
ans =
包含以下字段的 1×2 struct 数组:
name
number
grade
% rmfield作用是生成一个新structure,所以要处理student可以 student=rmfield(student,‘id')
结构体嵌套结构
结构体可以级联,即结构体中字段的取值也可以是结构体:
A = struct('data', [3 4 7; 8 0 1], ...
'nest', struct('testnum', 'Test 1', ...
'xdata', [4 2 8], ...
'ydata', [7 1 6]));
A(2).data = [9 3 2; 7 6 5];
A(2).nest.testnum = 'Test 2';
A(2).nest.xdata = [3 4 2];
A(2).nest.ydata = [5 0 9];
A
结构体的常用函数
函数 | 作用 |
---|---|
struct | 创建结构体 |
struct2cell | 将结构体转换为元胞数组 |
cell2struct | 将元胞数组转换为结构体 |
isstruct | 判断某变量是否是结构体 |
structfun | 对结构体的每个字段都应用某函数 |
fieldnames | 获取结构体的所有字段名 |
isfield | 判断结构体是否包含某字段 |
getfield | 获取结构体某字段的值 |
setfield | 为结构体中的某字段赋值 |
rmfield | 删除结构体中的某字段 |
orderfields | 为结构体字段排序 |
元胞数组(cell)
在MATLAB中,元胞数组是一个可以容纳不同类型元素的数据结构,类似于Python语言中的列表.
三种方式是等价的,其中第二种方式使用单元索引赋值,而第三种方式使用内容索引赋值.
- 有两种方式访问元胞数组中的数据,分别是: 单元索引()和内容索引{} .
A = { [1 4 3; 0 5 8; 7 2 9] 'Anne Smith' ;...
3+7i -pi:pi:pi}
A(1,1)={[1 4 3; 0 5 8; 7 2 9]};
A(1,2)={'Anne Smith'};
A(2,1)={3+7i};
A(2,2)={-pi:pi:pi};
A
A{1,1}=[1 4 3; 0 5 8; 7 2 9];
A{1,2}='Anne Smith';
A{2,1}=3+7i;
A{2,2}=-pi:pi:pi;
A
- 注意:在创建元胞数组时,工作区间不要有和元胞数组相同的变量名称,会报错!
不允许在不同类型之间赋值。
因为元胞数组的子集仍为元胞数组,在索引器内容的使用,我们有必要指明我们要访问的的是一个子元胞数组还是元胞数组对应区域中的内容.
- 使用单元索引() ,我们得到的是一个子元胞数组.
- 使用内容索引{} ,我们得到的是元胞数组对应区域中的内容.
```matlab
A(1,1)
ans =
1×1 cell 数组
{3×3 double}
A{1,1}
ans =
1 4 3
0 5 8
7 2 9
A{1,1}(1,3)
ans =
3
关于单元索引和内容索引的区别,请参考访问元胞数组中的数据[官方文档](https://ww2.mathworks.cn/help/matlab/matlab_prog/access-data-in-a-cell-array.html)
<a name="AlSkG"></a>
### 练习
• 创建具有以下内容的元胞数组结构体<br />
```matlab
A{1,1}='This is the first cell';
A{1,2}=[5+j*6 4+j*5];
A{2,1}=[1 2 3;4 5 6;7 8 9];
A{2,2}=cat(2,['Tim'], ['Chris']);
A
A =
2×2 cell 数组
{'This is the first cell'} {1×2 double}
{3×3 double } {'TimChris'}
A{1,1}={['This is the first cell']};
A{1,2}=[5+j*6 4+j*5];
A{2,1}=[1 2 3;4 5 6;7 8 9];
A{2,2}=[{'Tim','Chris'}];
A
A =
2×2 cell 数组
{1×1 cell } {1×2 double}
{3×3 double} {1×2 cell }
元胞数组的工作方式
指针
• 每个条目元胞数组包含一个指向数据的指针结构体
• 不同的细胞同一个细胞数组可以指向不同类型的数据结构
元胞数组的常用函数
函数 | 作用 |
---|---|
cell | 创建一个元胞数组 |
iscell | 判断某变量是否为元胞数组 |
cell2mat | 将元胞数组转为矩阵 |
cell2struct | 将元胞数组转为结构体 |
mat2cell | 将数组转换为指定大小元胞数组 |
num2cell | 将数组转换为相同大小的元胞数组 |
struct2cell | 将结构体转换为元胞数组 |
celldisp | 递归显示元胞数组中的内容 |
cellplot | 以图像形式绘制元胞数组的结构 |
cellfun | 对元胞数组的每个元胞应用某函数 |
cellstr | 从字符数组创建字符串元胞数组 |
nmu2cell( )和mat2cell( )
将矩阵(matrix)转换为单元变量
M = magic(n) 返回由 1 到 n2 的整数构成并且总行数和总列数相等的 n×n 矩阵。n 的阶数必须是大于或等于 3 的标量才能创建有效的幻方矩阵。
a = magic(3) %创建一个3*3的矩阵
b = num2cell(a)
c = mat2cell(a, [1 1 1], 3)
row列 column行
%%输出
a =
8 1 6
3 5 7
4 9 2
b =
3×3 cell 数组
{[8]} {[1]} {[6]}
{[3]} {[5]} {[7]}
{[4]} {[9]} {[2]}
c =
3×1 cell 数组
{1×3 double}
{1×3 double}
{1×3 double}
其中 mat2cell 函数可以在转换的时候指定元胞数组各元胞的尺寸.
a = magic(3)
b = num2cell(a)
% 得到
% [8] [1] [6]
% [3] [5] [7]
% [4] [9] [2]
c = mat2cell(a, [1 2], [2, 1])
% 得到
% [1x2 double] [6]
% [2x2 double] [2x1 double]
高维元胞数组(多维数组)
向量、矩阵、数组
一个三维的元胞数组可以有行(row),列(column),层(layer)三个维度.在对元胞数组进行索引时,优先级从高到低的顺序分别是: 行→列→层.
使用 cat ()函数可以在指定维度上对元胞数组进行拼接.
1行(row),2列(column),3层(layer)
使用reshape()函数
- 返回具有指定行和列的新数组
注意:在转换时r1n1=r2n2
>> A = {'James Bond', [1 2;3 4;5 6]; pi, magic(5)} %2*2
C = reshape(A,1,4) %1*4
A =
2×2 cell 数组
{'James Bond'} {3×2 double}
{[ 3.1416]} {5×5 double}
C =
1×4 cell 数组
{'James Bond'} {[3.1416]} {3×2 double} {5×5 double}
- 使用 reshape 从下面的矩阵 A 创建一个矩阵 B
判断变量数据类型的函数
下列函数可以对变量类型进行判断:
函数 | 作用 |
---|---|
isinteger | 判断输入参数是否为整型数数组 |
islogical | 判断输入参数是否为逻辑量数组 |
isnumeric | 判断输入参数是否为数值数组 |
isreal | 判断输入参数是否为实数数组 |
ischar | 判断输入参数是否为字符数组 |
iscell | 判断输入参数是否为元胞数组 |
isfloat | 判断输入数组是否为浮点数组 |
ishandle | 判断输入数组是否有效的图形句柄 |
isempty | 判断输入数组是否为空 |
isprime | 确定哪些数组元素为质数 |
isnan | 确定哪些数组元素为NaN |
isinf | 确定哪些数组元素为Inf |
isequal | 判断数组是否相等 |
文件读写
MATLAB支持的文件类型如下:
文件内容 | 扩展名 | 读取文件的函数 | 写入文件的函数 |
---|---|---|---|
MATLAB数据 | *.mat | load | save |
Excel表格 | .xls , .xlsx | xlsread | xlswrite |
空格分隔的数字 | *.txt | load | save |
读写MATLAB格式的数据
MATLAB工作区内的数据可以以*.mat格式保存在文件中.使用save函数将数据存入文件,使用load函数从文件中读取数据.
save函数的语法如下:
- save(filename,variables)将变量variables以二进制形式存入文件中
save(filename,variables,’-ascii’)将变量variables以文本形式存入文件中.
clear; a = magic(4); save mydata1.mat %二进制 save mydata2.mat -ascii %文本
load函数的语法如下:
load(filename)从二进制形式文件中读取数据.
- load(filename,’-ascii’)从文本形式文件中读取数据.
其中参数filename和variables都是字符串格式,若不指定variables参数,则将当前工作区内所有变量存入文件中.load('mydata1.mat') load('mydata2.mat','-ascii')
复杂的数据格式,如struct和cell ,不支持以二进制格式存储.读写Excel表格
使用 xlsread 和 xlswrite 函数可以读写Excel数据,语法如下:读取excel
读取Excel文件的语法: [num,txt,raw] = xlsread(filename,sheet,xlRange)```matlab Score = xlsread(‘04Score.xlsx’) %只读取数字 Score = xlsread(‘04Score.xlsx’, ‘B2:D4’) %以上两个操作结果一致 [Score Header] = xlsread(‘04Score.xlsx’)
%%输出 Score =
94 83 89
76 88 82
68 72 75
Header =
4×4 cell 数组
{0×0 char} {'Test1' } {'Test2' } {'Test3' }
{'John' } {0×0 char} {0×0 char} {0×0 char}
{'Selina'} {0×0 char} {0×0 char} {0×0 char}
{'Peter' } {0×0 char} {0×0 char} {0×0 char}
<a name="NVkNR"></a>
### 写入excel
写入Excel的语法: xlswrite(filename,A,sheet,xlRange) <br />操作
- 计算平均值并写入 Excel 电子表格
- 计算标准差并写出来进入列F
```matlab
M = mean(Score')';
%mean是列column operation
%mean(A)返回每列均值 以行矢量输出
%score上的小标点是score的转置
%因为要算的是一个人三次考试的平均数,算好之后在经过转置变成原样
xlswrite('04Score.xlsx', M, 1, 'E2:E4'); %数据输入
xlswrite('04Score.xlsx', {'Mean'}, 1, 'E1'); %表头
S = std(Score')';
xlswrite('04Score.xlsx',S,1,'F2:F4');
xlswrite('04Score.xlsx',{'标准差'},1,'F1');
%%例
A =
2 2 2
3 3 3
5 5 5
>> mean(A)
ans =
3.3333 3.3333 3.3333
Excel表格中获取文本
获取文本和数字
[Score Header] = xlsread('04Score.xlsx')
%%输出
数据和表头
文本和数字同时写入Excel
低级文件输入/输出
读写文件在字节或字符级别
• 文件具有 ID fid文件描述符
• 文件中的位置是由一个指针指定
功能 | 描述 |
---|---|
fopen | 打开文件,或获取有关打开文件的信息 |
fclose | 关闭文件 |
fscanf | 从文本文件中读取数据 |
fprintf | 将数据写入文本文件 |
feof | 将数据写入文本文件 |
- 打开或者关闭一个文件
例子:将正弦值写入文件
- 将正弦值写入文件
- 生成x,y
- 打开一个文件
- 将x,y写入文件
- 关闭文件!!!!
x = 0:(pi/10):pi; %从0到pi,间隔为pi/10
y = sin(x);
fid = fopen('sinx.txt','w');
for i=1:11
fprintf(fid,'%5.3f %8.4f\n', x(i), y(i));
end
fclose(fid); type sinx.txt
通过格式化 I/O 读写
例子
fid = fopen('04asciiData.txt'
,'r'); i = 1;
while ~feof(fid)
name(i,:) = fscanf(fid,'%5c',1);
year(i) = fscanf(fid,'%d',1);
no1(i) = fscanf(fid,'%d',1);
no2(i) = fscanf(fid,'%d',1);
no3(i) = fscanf(fid,'%g',1);
no4(i) = fscanf(fid,'%g\n');
i=i+1;
end
fclose(fid);