本节介绍 MATLAB 表格(table):按列组织数据,每列具有变量名,且各列的类型可以不同,语义上接近带表头的电子表格。数值矩阵要求元素类型一致,无法直接为每一列命名;元胞数组虽可混合类型,却不自带列名体系。需要按「姓名、年龄、身高」这类报表结构存放数据时,表格比平行数组或元胞网格更合适。
table 是 MATLAB 提供的类型。GNU Octave 以及本站在线编译器通常没有该类型,本节示例供对照查阅;在线练习时可用结构体或元胞数组完成相近的组织方式。
创建 table
先为每一列准备同长度的变量,再一并交给 table。列名默认取这些变量的名字:
Name = {'Riya'; 'Siya'; 'Tiya'};
Age = [25; 30; 28];
Height = [160; 175; 168];
Weight = [55; 70; 65];
T = table(Name, Age, Height, Weight)显示时每列有表头,行按记录排列,例如第一行是 Riya、25、160、55。文本列用元胞数组(或 string 数组)存放,数值列用普通列向量存放,二者可以出现在同一张表中。各列的行数必须一致,否则无法对齐成表。
访问列:点号
取出某一列时,写法与结构体字段相近,使用 T.列名。需要取子表(仍保持 table 类型)时,用圆括号并写下标或列名:
T.Age % 一整列(列向量)
T.Age(1) % 第一行的 Age,得到 25
T(1, :) % 第一行,结果仍是 table
T(1:2, 'Age') % 前两行的 Age 列,结果仍是 tableT.Age 返回的是该列内部的数组,可直接做数值运算;T(1:2, 'Age') 返回的是缩小后的表格,还带有列名。若随后要把这一列交给 mean 等函数,应使用 T.Age,而不是尚未解包的子表。
增删行列
T.BMI = T.Weight ./ (T.Height/100).^2; % 新增一列
T(4, :) = {'Niya', 26, 170, 60}; % 追加一行
T(:, 'Weight') = []; % 删除 Weight 列新增列时,右侧表达式的长度须与现有行数一致;这里用点运算按行计算体质指数。追加一行时,用元胞数组按列顺序提供各字段。删除某一列写成 T(:, '列名') = [],与删除矩阵的某一列写法相同。
和 cell、普通数组互转
C = table2cell(T); % 表格到 cell
T2 = cell2table(C, 'VariableNames', {'Name','Age','Height','Weight'});
A = table2array(T(:, 'Age')); % 单列数值转普通数组需要交给只接受数值矩阵的函数时,先把相应列转为数组。需要按格子混合存放、不再使用列名时,再转为元胞数组。互转时注意列名须另行指定,不会自动从元胞的内容里读出来。
读取 CSV / Excel 直接变表格
本地 MATLAB 中,带表头的 CSV 或 Excel 可用 readtable 一次读成表格:
T = readtable('data.csv') % CSV 自动识别表头
T = readtable('data.xlsx') % Excel 也能读写回文件用 writetable:
writetable(T, 'out.csv')本站在线编译器不提供磁盘文件,上述导入导出无法在该环境中验证。Octave 用户可改用 csvread、dlmread 或上一章的 importdata 读入数值,再自行组织为结构体或元胞数组。
自查清单
- 表格的某一列如何用点号取出,并交给
mean计算? - 给表格追加一列,右侧表达式的长度应满足什么条件?
- table 与 cell 如何互转?单列如何变成普通数组?
- 读 CSV 文件直接得到表格,在 MATLAB 中用哪个函数?
- 学号这类可能含前导零的文本,为什么不宜放进纯数值列?
本节说明了 table 的创建、点号访问列、增删行列,以及与元胞数组、普通数组的互转和 readtable / writetable 的用法。下一节介绍数据容器:对照普通数组、元胞数组、结构体与表格的适用场景。