2. 表格数据导入与初步探查

在MATLAB中处理表格数据,第一步永远不是急着写计算逻辑,而是把数据“看清楚”。CSV和Excel文件看似简单,但列名是否规范、数值列是否被误读成字符、缺失值以什么形式出现,都会直接影响后续的批量计算。本节围绕三个导入函数——readtable、readcell、detectImportOptions——讲清楚它们各自适合什么场景,以及导入后如何用变量类型、维度、摘要统计和缺失值分布四项检查建立对数据的整体认识。

三个导入函数的分工

readtable是最常用的入口,它把数据读成table类型,每列自动推断类型,列名来自首行表头,适合“规整的二维表”——即首行是变量名、每列语义一致的数据。对于纯数值矩阵,它同样可用,但更推荐readmatrix;本节聚焦表格场景,因此以readtable为主线。

readcell则把整个区域读成cell数组,不做类型推断,每个元素保持原始内容。它的价值在于“先看清楚再决定”:当文件表头有多行、存在合并单元格、或数值列中混有“N/A”“—”这类文本时,readtable可能把整列判为字符型,而readcell能原样保留,便于你逐格检查后再手工整理。

detectImportOptions是“先配置、后读取”的桥梁。它扫描文件前若干行,返回一个导入选项对象,你可以修改其中的VariableNames、VariableTypes、TreatAsMissing、Delimiter等属性,再传给readtable。当文件格式固定、需要反复导入时,把选项对象保存下来复用,能保证每次读入的列类型完全一致,避免“这次读成double、下次读成char”的隐患。

% 示例:先探测再读取,显式指定缺失标记
opts = detectImportOptions('sensor_log.csv');
opts.VariableNames = {'ID','Time','Temp','Pressure','Status'};
opts.VariableTypes = {'double','datetime','double','double','categorical'};
opts = setvaropts(opts,'Temp','TreatAsMissing',{'NA','--'});
T = readtable('sensor_log.csv',opts);

上面这段示例中,Time列被显式指定为datetime,Status指定为categorical,Temp列中的“NA”和“--”统一视为缺失。这些设定属于教学示例,实际文件需按真实表头调整。

导入后的四项探查

数据读进来只是开始,接下来要做四项检查,它们共同回答“这份数据能不能直接用于计算”。

变量类型:用T.Properties.VariableNames看列名,用varfun(@class,T,'OutputFormat','cell')或直接查看T的显示摘要,确认每列是double、datetime、categorical还是cell。数值列若显示为cell或char,说明混入了非数值字符,必须回到导入选项处理。

维度:size(T)给出行数和列数,height(T)与width(T)更直观。行数应与业务预期一致,比如一个传感器每天应产生288条5分钟记录,若读入只有200条,就要怀疑分隔符或空行处理有问题。

摘要统计:summary(T)一次性输出每列的最小值、中位数、最大值、缺失数量和类型,是最高效的初探工具。对数值列重点看极值是否离谱(如温度出现999),对分类列看类别数量是否合理。

缺失值分布:summary已给出每列缺失数,但分布位置同样重要。可用ismissing(T)得到逻辑矩阵,再按列求和定位缺失集中的列;对时间序列,还可按行统计缺失比例,判断缺失是零星出现还是整段中断。

summary(T)                          % 各列统计与缺失数
missCount = sum(ismissing(T),1)     % 每列缺失个数
rowMissRatio = sum(ismissing(T),2)/width(T);
find(rowMissRatio > 0.5)            % 缺失超过一半的行

下面的图示把“导入方式选择—四项探查—判断分流”组织成一条可对照的检查路径,帮助你在拿到一份新文件时快速定位该用哪个函数、该看哪些指标。

表格数据导入与初步探查路径 CSV / Excel 文件 表头、分隔符、缺失标记 readtable 规整二维表,自动推断类型 首选入口 readcell 多行表头 / 混合内容 原样保留,逐格检查 detectImportOptions 先配置列名/类型/缺失标记 再交给 readtable table T 统一的数据容器 ① 变量类型 VariableNames varfun(@class,…) 数值列误判为 char? ② 维度 size / height / width 行数是否符合预期 空行或分隔符异常? ③ 摘要统计 summary(T) 最小值 / 中位数 / 最大值 极值是否离谱? ④ 缺失值分布 ismissing(T) 按列计数 / 按行比例 整段中断还是零星? 四项检查全部通过,方可进入清洗与批量计算;任一项异常,回到导入选项修正后重读

从探查结果到处理决策

四项检查不是走形式,每一项都对应一个明确的处理动作。若变量类型检查发现某数值列是cell,说明该列混有文本,应回到detectImportOptions用TreatAsMissing把占位符声明为缺失,或改用readcell逐格定位异常文本。若维度不符,优先检查分隔符和空行:CSV中若字段内本身含逗号,必须用引号包裹,否则列数会错位;Excel中若首行是标题而非表头,需设置DataRange或VariableNamesRange跳过。

摘要统计的极值是最容易被忽视的线索。温度列最大值出现999、压力列出现负数,往往不是真实测量而是传感器故障码或单位错误。此时不要急于删除,先用T(T.Temp > 200,:)把可疑行筛出来,结合时间列判断是单点异常还是整段偏移。缺失值分布则决定后续策略:若某列缺失比例超过30%,直接删除该列可能比插补更稳妥;若缺失集中在某几个时间段,应检查采集设备在那段时间是否离线,而不是简单用均值填充。

建议把四项探查写成一个小函数,每次导入新文件后自动打印列类型、行列数、各列缺失数和极值,形成固定的“数据体检”习惯。对于需要反复导入的同类文件,把detectImportOptions得到的选项对象用save保存为mat文件,下次直接load后传给readtable,可彻底消除类型漂移。

完成上述检查后,你对数据的列语义、规模、异常点和缺失格局已经有了清晰判断,这才具备进入清洗与批量计算的条件。反过来,如果跳过探查直接写循环计算,一旦某列被误读为字符,后续的数值运算会在运行时才报错,排查成本远高于导入阶段多花的两分钟。