MATLAB数据清洗流程包含:缺失值处理/异常值检测/重复值删除

文章目录

前言

数据清洗是数据分析、建模前的核心步骤,直接影响后续结果的准确性。MATLAB作为科研、工程领域常用的数据分析工具,内置丰富函数可高效完成缺失值处理、异常值检测、重复值删除等操作。

一、数据准备(基础操作)

在开始清洗前,先导入待处理数据(以CSV格式为例),MATLAB支持多种格式(Excel、TXT、MAT)导入,核心代码如下:

matlab 复制代码
% 导入CSV数据,data为数据表,text为表头(按需选择)
data = readtable('待清洗数据.csv'); 
% 查看数据基本信息(行数、列数、数据类型、缺失值概览)
summary(data); 

关键说明readtable是MATLAB导入表格数据的核心函数,summary可快速定位缺失值、数据类型异常等问题,是数据清洗的第一步。

二、缺失值处理(4种常用方法)

缺失值(NaN/空值)是数据清洗中最常见的问题,MATLAB提供多种处理方式,需根据数据场景选择:

1. 查看缺失值分布

先定位缺失值位置和数量,避免盲目处理:

matlab 复制代码
% 统计每列缺失值数量
missing_count = sum(ismissing(data)); 
% 查看缺失值位置(返回逻辑矩阵,1表示缺失)
missing_pos = ismissing(data); 
% 筛选出包含缺失值的行
missing_rows = data(any(missing_pos,2),:); 

2. 删除缺失值(适用于缺失率<5%)

若缺失值占比极低,可直接删除含缺失值的行/列,操作简单且不影响整体数据分布:

matlab 复制代码
% 删除所有含缺失值的行(最常用)
data_clean1 = rmmissing(data); 
% 仅删除指定列(如第2列)含缺失值的行
data_clean2 = rmmissing(data,'Variables',2); 
% 删除整列缺失值占比>50%的列
col_missing_rate = sum(ismissing(data))./height(data);
data_clean3 = data(:,col_missing_rate<0.5); 

3. 填充缺失值(适用于缺失率5%-20%)

当缺失值占比适中,填充是更合理的方式,MATLAB支持均值、中位数、线性插值等填充:

matlab 复制代码
% 数值型列:均值填充(适用于正态分布数据)
data_filled1 = fillmissing(data,'constant',mean(data,'omitNaN')); 
% 数值型列:中位数填充(适用于偏态分布数据,抗异常值干扰)
data_filled2 = fillmissing(data,'constant',median(data,'omitNaN')); 
% 时间序列数据:线性插值填充(保持数据趋势)
data_filled3 = fillmissing(data,'linear'); 
% 分类变量:众数填充(适用于字符/分类列)
for i = 1:width(data)
    if iscategorical(data(:,i)) || ischar(data(:,i))
        [mode_val,~] = mode(data(:,i),'omitNaN');
        data_filled4(:,i) = fillmissing(data(:,i),'constant',mode_val);
    end
end

4. 模型预测填充(适用于缺失率20%-50%)

缺失值占比较高时,用机器学习模型预测填充更精准(以线性回归为例):

matlab 复制代码
% 提取无缺失值的样本作为训练集
no_missing = rmmissing(data); 
% 选择特征列(如1-3列)预测缺失列(第4列)
X = no_missing(:,1:3); 
y = no_missing(:,4);
% 训练线性回归模型
mdl = fitlm(X,y); 
% 预测缺失值并填充
missing_idx = ismissing(data(:,4));
data_pred = data;
data_pred(missing_idx,4) = predict(mdl,data(missing_idx,1:3)); 

三、异常值检测与处理(3种核心方法)

异常值(离群点)会扭曲统计结果,MATLAB可通过统计、聚类、箱线图等方法检测:

1. 箱线图法(最直观,适用于单变量)

箱线图基于四分位数(IQR)识别异常值,超出"Q3+1.5IQR"或"Q1-1.5IQR"的即为异常值:

matlab 复制代码
% 绘制指定列(如第2列)箱线图,直观查看异常值
boxplot(data,'Variables',2); 
% 计算四分位数和IQR,定位异常值
q = quantile(data(:,2),[0.25,0.75]);
iqr_val = q(2)-q(1);
upper_limit = q(2)+1.5*iqr_val;
lower_limit = q(1)-1.5*iqr_val;
% 筛选异常值位置
outlier_idx = (data(:,2)>upper_limit) | (data(:,2)<lower_limit); 

2. 标准差法(适用于正态分布数据)

基于"均值±3倍标准差"原则,超出范围的判定为异常值:

matlab 复制代码
% 计算均值和标准差(忽略缺失值)
mu = mean(data(:,2),'omitNaN');
sigma = std(data(:,2),'omitNaN');
% 定位异常值
outlier_idx = abs(data(:,2)-mu) > 3*sigma; 

3. 异常值处理方式

检测到异常值后,根据场景选择处理方法:

matlab 复制代码
% 方法1:删除异常值(适用于异常值占比<1%)
data_out1 = data(~outlier_idx,:); 
% 方法2:替换为边界值(避免数据量减少,适用于连续数据)
data_out2 = data;
data_out2(outlier_idx,2) = upper_limit; % 上边界替换
% 方法3:缩尾处理(替换为99%/1%分位数,适用于偏态数据)
p99 = quantile(data(:,2),0.99,'omitNaN');
p01 = quantile(data(:,2),0.01,'omitNaN');
data_out3 = data;
data_out3(data_out3(:,2)>p99,2) = p99;
data_out3(data_out3(:,2)<p01,2) = p01;

四、重复值删除(快速去重)

重复值会导致统计结果偏高,MATLAB可一键识别并删除重复行/列:

1. 查看重复值

先定位重复行的位置和数量:

matlab 复制代码
% 识别重复行(返回逻辑矩阵,1表示重复行)
is_duplicate = isduplicate(data); 
% 统计重复行数量
duplicate_count = sum(is_duplicate); 
% 查看所有重复行
duplicate_rows = data(is_duplicate,:); 

2. 删除重复值

保留首次出现的行,删除后续重复行(最常用):

matlab 复制代码
% 删除重复行,保留第一行
data_unique1 = unique(data,'rows','stable'); 
% 仅删除指定列(如1-2列)重复的行
[data_unique2,~,~] = unique(data(:,1:2),'rows','stable');
data_unique2 = data(data_unique2,:); 
% 完全重复的列删除(适用于多列数据重复)
data_unique3 = data(:,~isduplicate(data','rows')); 

五、完整数据清洗案例(实战)

以"工业传感器数据.csv"为例,整合缺失值、异常值、重复值处理全流程:

matlab 复制代码
% 1. 导入数据
data = readtable('工业传感器数据.csv');
summary(data);

% 2. 缺失值处理(中位数填充数值列,众数填充分类列)
data_filled = data;
for i = 1:width(data)
    if isnumeric(data_filled(:,i))
        data_filled(:,i) = fillmissing(data_filled(:,i),'constant',median(data_filled(:,i),'omitNaN'));
    elseif iscategorical(data_filled(:,i))
        [mode_val,~] = mode(data_filled(:,i),'omitNaN');
        data_filled(:,i) = fillmissing(data_filled(:,i),'constant',mode_val);
    end
end

% 3. 异常值处理(箱线图法+边界值替换)
q = quantile(data_filled(:,3),[0.25,0.75]);
iqr_val = q(2)-q(1);
upper = q(2)+1.5*iqr_val;
lower = q(1)-1.5*iqr_val;
outlier_idx = (data_filled(:,3)>upper) | (data_filled(:,3)<lower);
data_filled(outlier_idx,3) = upper;

% 4. 重复值删除
data_clean = unique(data_filled,'rows','stable');

% 5. 保存清洗后的数据
writetable(data_clean,'清洗后_工业传感器数据.csv');
disp('数据清洗完成!清洗后数据行数:');
disp(height(data_clean));
相关推荐
SmoothSailingT2 小时前
C#——textBox控件(1)
开发语言·c#
悦悦子a啊2 小时前
使用 Java 集合类中的 LinkedList 模拟栈以此判断字符串是否是回文
java·开发语言
Lucky小小吴2 小时前
java代码审计入门篇——Hello-Java-Sec(完结)
java·开发语言
csbysj20202 小时前
XML 技术
开发语言
清晓粼溪2 小时前
Java登录认证解决方案
java·开发语言
小徐Chao努力2 小时前
Go语言核心知识点底层原理教程【变量、类型与常量】
开发语言·后端·golang
锥锋骚年2 小时前
go语言异常处理方案
开发语言·后端·golang
沐知全栈开发2 小时前
JSP 自动刷新技术详解
开发语言
特立独行的猫a2 小时前
C++使用Boost的Asio库优雅实现定时器与线程池工具类
开发语言·c++·线程池·定时器·boost·asio