3. 表格变量访问与索引操作

在 MATLAB 中,table 是一种为“列向异构数据”设计的容器:每一列是一个变量,可以拥有自己的类型(数值、字符串、分类、日期时间、元胞等),但所有变量共享相同的行数。正因为这种“按列组织”的结构,table 的索引体系比普通数值矩阵更丰富,也更容易混淆。本节围绕三种括号与点号访问方式展开,并给出子集提取与快速查看的实用方法。

三种索引符号的分工

理解 table 索引的关键,是先分清“你要拿到的是子表、变量内容,还是变量容器”。MATLAB 用三种符号表达这三种意图:

  • 圆括号 T(rows, vars):返回一个新的 table(子表),保留变量名与类型。行、列位置都可以用数字、逻辑向量、变量名或 : 指定。
  • 点号 T.VarName:直接取出某一列的数据内容,返回该变量本身的类型(数值列返回数值向量,字符串列返回 string 数组)。这是最常用的取数方式。
  • 花括号 T{rows, vars}:取出内容并尝试拼接为矩阵或元胞数组,适合需要把多列数值合并成一个数值矩阵参与运算的场合。

一个常见的误区是把 T(:, 2) 与 T{:, 2} 混用。前者得到的是只含一个变量的 table,直接参与算术运算会报错;后者得到的是该列的原始数值向量,可以直接计算。判断标准很简单:要保留表格结构就用圆括号,要拿数据本身就用点号或花括号。

table 索引:三种符号,三种返回结果 源表 T(4 行 3 变量) ID Name Score 1 "A" 88 2 "B" 92 3 "C" 75 4 "D" 96 T(2:3, ["Name","Score"]) 返回 table(子表) 保留变量名与类型 T.Score 返回数值列向量 [88; 92; 75; 96] T{:, ["ID","Score"]} 拼接为数值矩阵 4×2 double 选择依据 圆括号 → 保留表结构 用于筛选、再导出 点号 → 取单列数据 用于统计、绘图 花括号 → 取内容拼接 用于矩阵运算 注意:T(:,2) 是表, 不能直接参与算术

行、列与变量子集的提取

实际处理数据时,最常见的需求是“按条件筛行、按名称选列”。行方向可以用逻辑向量表达条件,例如从一张学生成绩表中取出不及格记录:

T = table([1;2;3;4], ["A";"B";"C";"D"], [88;92;75;96], ...
    'VariableNames', ["ID","Name","Score"]);

lowScore = T(T.Score < 90, :);          % 逻辑索引筛行,保留全部变量
nameScore = T(:, ["Name","Score"]);      % 按变量名选列
sub = T(2:3, ["Name","Score"]);          % 行区间 + 列名组合

这里 T.Score < 90 生成逻辑向量 [1;0;1;0],作为行下标传入圆括号,得到只含 A、C 两行的子表。列方向推荐使用变量名字符串数组而非列序号,因为变量名在增删列后依然稳定,可读性也更好。若变量名含空格或特殊字符,需写成 T.("Total Score") 形式。

需要提醒的是,table 的行下标与变量下标是两套独立维度,写 T(1, 1) 得到的是“第 1 行第 1 个变量”构成的 1×1 子表,而不是一个标量。若确实想取单个单元格的值,应使用 T{1, 1} 或 T.ID(1)。

head、tail 与 summary 的快速查看

面对几十列、上万行的表,先“看几眼”再动手,是避免索引错误的有效习惯。三个函数各有侧重:

函数作用典型用途
head(T, n)显示前 n 行(默认 8 行)确认变量名、数据类型与前几行取值格式
tail(T, n)显示后 n 行检查数据尾部是否有缺失、异常或截断
summary(T)逐变量给出类型与统计摘要快速判断哪些列是数值、哪些含缺失、取值范围是否合理

summary 对数值变量给出最小值、中位数、最大值,对分类变量给出各类别计数,对含缺失的列会明确标出缺失数量。它不改变数据,只是把“表的结构画像”打印出来,非常适合在写筛选条件之前先确认列名拼写和类型是否符合预期。

一个完整的筛选与核对流程

假设要统计成绩不低于 90 分的学生平均分,并保留其姓名。合理的操作顺序是:先用 summary(T) 确认 Score 为数值列且无缺失;再用逻辑索引筛行;最后用点号取列计算均值。

summary(T)                       % 确认 Score 为 double,无缺失
pass = T(T.Score >= 90, :);      % 子表:B、D 两行
avgScore = mean(pass.Score);     % 点号取列,直接求均值 → 94
names = pass.Name;               % 字符串列,返回 string 数组

若把最后一步误写成 mean(pass(:, "Score")),MATLAB 会对 table 求均值而报类型错误,这正是圆括号与点号分工的体现。养成“筛选用圆括号、计算用点号”的习惯,可以规避大部分 table 索引问题。

当变量名是动态生成的(例如循环中拼接的列名),可用 T.(varName) 动态访问;批量选列时用 T(:, varNames) 传入字符串数组,比逐个点号访问更简洁。
花括号索引 T{rows, vars} 在所选列类型不一致时会返回元胞数组而非矩阵,后续运算前应先检查 class 结果,避免隐式转换带来的意外。