3. 工程数据导入与接口

工程数据分析的第一步往往不是建模,而是把散落在不同载体里的数据可靠地读进 MATLAB 工作区。工程现场的数据来源通常高度异构:试验室台账多为 Excel,采集系统导出 CSV,设备日志是带时间戳的文本,历史工况存在数据库,而在线监测则来自传感器串口或网络流。本节围绕“读得进、读得对、读得可追溯”三个目标,梳理 MATLAB 中对应的接口与关键参数。

一、先判断数据形态,再选读取函数

选择读取方式的核心依据是:数据是规则表格还是非规则文本、是否含表头与单位行、数值与文本是否混排、文件规模有多大。规则二维表优先用 readtable,它能自动识别变量名与类型,返回 table 便于按列名访问;纯数值矩阵可用 readmatrix;需要保留原始文本行、处理非规则日志时用 readlines 或 fgetl 逐行解析;数据库走 Database Toolbox 的 database/fetch;实时传感器则用 serialport 或 tcpclient 建立流式接口。

多源异构工程数据导入接口与统一数据模型 Excel 台账 .xlsx / 多工作表 CSV 采集导出 逗号/分号分隔 文本/传感器日志 时间戳 + 键值行 关系数据库 SQL 查询结果集 在线传感器流 串口 / TCP 实时帧 MATLAB 读取接口 readtable / readcell Sheet、Range、VariableNamingRule readmatrix / detectImportOptions Delimiter、NumHeaderLines readlines / textscan 正则提取、逐行解析 database / fetch JDBC 驱动、SQL 语句 serialport / tcpclient 波特率、终止符、回调 统一为 timetable / table 统一数据模型(timetable) 时间列 Time(datetime,统一时区) 测点列:转速、温度、压力、振动 单位与量纲元数据(VariableUnits) 缺失值标记 NaN / 异常标记 数据来源与导入时间(可追溯) 归一

二、Excel 与 CSV:把“表头陷阱”处理干净

工程 Excel 常见问题是前几行是标题、单位或合并单元格,真正的表头在第 3 行。此时应显式指定参数,而不是依赖自动识别:

opts = detectImportOptions('test_data.xlsx', ...
    'Sheet','Sheet1', 'Range','A3:F200', ...
    'VariableNamingRule','preserve');
opts.VariableTypes = {'datetime','double','double','double','double','string'};
T = readtable('test_data.xlsx', opts);

其中 VariableNamingRule 设为 preserve 可保留“转速(rpm)”这类含括号和中文的列名,避免被自动改成非法标识符。VariableTypes 显式声明类型,能防止“时间列被读成文本”或“含空值的数值列被读成 cell”。CSV 若使用分号分隔、小数点用逗号(欧洲格式),需设置 Delimiter',';' 与 DecimalSeparator',',',否则数值会整列变成字符串。

三、文本与传感器日志:按行解析再结构化

设备日志通常形如 2024-05-12 08:31:02.145, RPM=1480.2, TEMP=76.4, VIB=2.31。这类非规则文本不适合直接 readtable,应逐行读取后用正则提取:

lines = readlines('sensor_log.txt');
pat = '(\S+ \S+),\s*RPM=([\d.]+),\s*TEMP=([\d.]+),\s*VIB=([\d.]+)';
tok = regexp(lines, pat, 'tokens', 'once');
ok = ~cellfun(@isempty, tok);
t = datetime(cellfun(@(c) c{1}, tok(ok), 'uni', 0), ...
    'InputFormat','yyyy-MM-dd HH:mm:ss.SSS');
rpm = cellfun(@(c) str2double(c{2}), tok(ok));
temp = cellfun(@(c) str2double(c{3}), tok(ok));
vib = cellfun(@(c) str2double(c{4}), tok(ok));
TT = timetable(rpm, temp, vib, 'RowTimes', t);

关键点是先用 ok 掩码剔除解析失败的行(如设备重启提示行),再统一构造 timetable。若日志时间戳无时区,应在导入时用 TimeZone 属性显式声明,避免后续多源合并时出现 8 小时偏移。

四、数据库与实时流:连接、查询与回调

数据库导入先建立连接再取数,示例(需已配置 JDBC 驱动):

conn = database('plantdb','user','pwd', ...
    'Vendor','MySQL','Server','10.20.3.15','PortNumber',3306);
sql = ['SELECT ts, rpm, temp FROM run_log ' ...
       'WHERE ts BETWEEN ''2024-05-01'' AND ''2024-05-31'''];
rows = fetch(conn, sql);
close(conn);
TT = table2timetable(rows, 'RowTimes','ts');

实时传感器用 serialport 打开端口并注册回调,把每帧数据追加进缓冲区,避免阻塞主流程:

s = serialport('COM5', 115200, 'Timeout', 2);
configureTerminator(s, 'CR/LF');
s.UserData = timetable();
configureCallback(s, 'terminator', @(~,~) appendFrame(s));
% appendFrame 内:readline -> 解析 -> 追加到 s.UserData

五、导入后的自检清单

数据读进来不等于读对了。建议每次导入后执行四项检查:一是行数与源文件记录数是否一致;二是时间列是否单调递增、有无重复或跳变;三是数值列的极值与量程是否合理(如转速不应为负、温度不应超过 200 ℃);四是缺失值比例,若某测点缺失超过 5% 需在报告中标注。可用 summary(TT) 快速查看各列类型、缺失与分位数,用 isregular(TT) 判断采样是否等间隔。只有通过自检的数据,才适合进入后续清洗与特征提取环节。

多源数据合并时,务必先统一时间基准与单位。例如把 Excel 中的“转速(rpm)”和数据库中的“speed(rad/s)”换算到同一量纲后再 synchronize,否则后续趋势对比会得出错误结论。