MATLAB - 表格
MATLAB - 使用表进行现代数据处理
Section titled “MATLAB - 使用表进行现代数据处理”在现代数据分析中,数据很少是均匀的。您经常处理包含文本、数字和日期混合的数据集。MATLAB 的 table 数据结构是专门为此目的设计的。表是一个存储数据列的容器,其中每列可以具有不同的数据类型,但所有列必须具有相同行数。
表是现代 MATLAB 工作流程的基石,提供了一种直观、灵活、高效的方式来组织、清理和分析表格数据,类似于电子表格或数据库表。
表与矩阵:关键区别
Section titled “表与矩阵:关键区别”了解何时使用表而非传统矩阵至关重要。
| 特性 | 矩阵 | 表 |
|---|---|---|
| 数据类型 | 同构:所有元素必须是相同类型(例如,double)。 | 异构:每列可以是不同类型(例如,string、double、datetime)。 |
| 数据访问 | 数值索引:A(row, col)。依赖于记住数值位置。 | 命名索引:T.VariableName 或 T(:, 'VariableName')。代码更具可读性和鲁棒性。 |
| 元数据 | 不支持列名或行标识符等内置元数据。 | 内置变量(列)名、行名和描述属性。 |
| 用例 | 线性代数、数学计算、图像处理。 | 数据分析、从文件(CSV、Excel)导入混合类型数据、统计建模。 |
创建 MATLAB 表
Section titled “创建 MATLAB 表”table() 函数是创建表的主要方式。您可以从现有工作区变量创建表,或预分配它们以用于未来的数据。
% 从现有列向量创建T = table(col1, col2, ..., colN);
% 创建并指定变量名T = table(col1, col2, 'VariableNames', {'name1', 'name2'});
% 预分配一个表T = table('Size', [numRows, numCols], 'VariableTypes', {'type1', 'type2', ...});示例 1:创建一个简单的患者数据表
Section titled “示例 1:创建一个简单的患者数据表”让我们从单独的数组创建一个表。请注意,名称使用了现代 string 数组,它比字符单元数组更灵活。
% 1. 定义列数据LastName = ["Smith"; "Jones"; "Williams"; "Brown"]; % 现代字符串数组Age = [38; 43; 38; 40];IsSmoker = [true; false; true; false];Height = [71; 69; 64; 67];
% 2. 创建表% MATLAB 自动使用变量名作为列标题patientData = table(LastName, Age, IsSmoker, Height)执行后,MATLAB 会显示一个干净、格式化的表:
patientData =
4x4 table
LastName Age IsSmoker Height ___________ ___ ________ ______
"Smith" 38 true 71 "Jones" 43 false 69 "Williams" 38 true 64 "Brown" 40 false 67示例 2:预分配和填充表
Section titled “示例 2:预分配和填充表”当您知道数据的最终大小时,预分配是高效的,尤其是在循环中收集数据时。
% 定义表结构numRows = 5;varTypes = {'string', 'double', 'datetime'};varNames = {'SensorID', 'Reading', 'Timestamp'};
% 预分配表sensorLog = table('Size', [numRows, numel(varTypes)], ... 'VariableTypes', varTypes, ... 'VariableNames', varNames);
% 填充表(例如,在循环中)for i = 1:numRows sensorLog.SensorID(i) = "Sensor_" + i; sensorLog.Reading(i) = rand() * 100; sensorLog.Timestamp(i) = datetime('now') + days(i);end
disp(sensorLog);访问和修改表数据
Section titled “访问和修改表数据”现代 MATLAB 对大多数表操作使用直观的点表示法,使您的代码清晰易读。
让我们使用第一个示例中的 patientData 表。
% 访问单列(返回一个向量)ages = patientData.Age;
% 从该列访问单个元素firstPatientAge = ages(1); % 返回 38
% --- 直接访问 ---
% 使用点表示法和行索引访问特定元素firstPatientAge_direct = patientData.Age(1); % 返回 38
% 访问多列(返回一个新的、较小的表)personalInfo = patientData(:, {'LastName', 'Age'});
% 使用数值索引或逻辑索引访问行allSmokers = patientData(patientData.IsSmoker, :);
% --- 修改数据 ---
% 修改单个值patientData.Age(2) = 44; % 更新 Jones 的年龄
% 添加新列patientData.Weight = [176; 163; 131; 155];disp(patientData);就像列名一样,您可以分配唯一的行名以便于查找。
% 使用患者的姓氏作为唯一的行标识符patientData.Properties.RowNames = patientData.LastName;
% 现在您可以通过行名访问数据% 注意:字符向量使用花括号 {},表使用圆括号 ()smithsData_table = patientData('Smith', :); % 返回一个 1 行的表
williamsAge = patientData{'Williams', 'Age'}; % 返回标量值 38实用技巧和最佳实践
Section titled “实用技巧和最佳实践”- 快速概览:使用
summary(T)获取表中每个变量的统计摘要。这对于初步数据探索非常有用。 - 处理缺失数据:表内置支持缺失值(例如,数字为
NaN,字符串为<missing>)。ismissing和fillmissing等函数旨在与表无缝协作。 - 性能:对于非常大的数据集,预分配表比在循环中增长表要快得多。
- 可读性:访问单列时,始终使用点表示法 (
T.VariableName)。它更快,并且比T(:, 'VariableName')更清晰地表达您的代码意图。