MATLAB数据预处理之缺失值插补

2023-11-18


前言

   现实中采集的原始数据不一定满足预测模型的需求,往往在使用之前需要对原始数据进行处理,使得采集的原始数据满足需求,本文主要做的是数据缺失处理方法。

1 加载原始数据

load('pm25data.mat')% 原始数据
figure
t = datetime(2010,1,2,0,0,0) + hours(0:length(pm25data)-1)';% 创建与数据对应的时间向量。
plot(pm25data)% 查看波形
title('原始数据波形')
xlabel('Time/h');
ylabel('PM_{2.5} / (\mu g.m^{-3})');

   如下图所示,可以看到原始数据波形有缺失部分
在这里插入图片描述

2 查找缺失值并填充缺失值

% -------------------------------------------------------------------------
% 查找缺失值
% -------------------------------------------------------------------------
TF1=ismissing(pm25data);% 查找缺失值,TF是逻辑矩阵,利用TF可以找到pm25data内的缺失值
%     plot(t,TF1,'*') % TF中的1对应pm25data中的缺失值
%     pm25data(TF1) % 显示缺失值位置
TF = TF1;
% -------------------------------------------------------------------------
% 填充缺失值 (pm25dataPre是插补后的数据)
% -------------------------------------------------------------------------
pm25dataPre = pm25data;
t = datetime(2010,1,2,0,0,0) + hours(0:length(pm25data)-1)';% 创建与数据对应的时间向量。
while max(TF) % 如果还存在缺失值就继续插补
    % pm25data = fillmissing(pm25data,'movmean',30);% 使用窗口长度为 30 的移动均值填充缺失数据。
    pm25dataPre = fillmissing(pm25dataPre,'movmedian',30); % 使用窗口长度为 30 的移动中位数替换数据中的 NaN 值 
    TF=ismissing(pm25dataPre);% 查找数据中的缺失值,TF是逻辑矩阵,利用TF可以找到pm25data内的缺失值
end
%     plot(TF) % TF中的1对应pm25data中的缺失值,当数据中的缺失值填充完时,可以看到TF的值全为0
plot(t,pm25dataPre,t(TF1),pm25dataPre(TF1),'x')% 查看插补后的数据 pm25dataPre
title('插补后的数据波形')
xlabel('Time/h');
ylabel('PM_{2.5} / (\mu g.m^{-3})');
legend('原始数据','插补值')    
%     save('pm25dataPre.mat','pm25dataPre');% 保存插补后的数据

可以看到数据缺失部分,已被补全
在这里插入图片描述


总结

   以上就是今天要讲的内容,数据是pm2.5数据。如有不合理的地方还请指出。


2021年4月5日09:51:56更新


问:如何用缺失值的前两个值的平均值进行插补?

  对于一个一维向量 A = [x1,x2,x3,x4,x5,x6],其值如下表所示:

A x1 x2 x3 x4 x5 x6
Value 5 7 8 9

  可以看到x3和x6值缺失,对于x3进行插补,则
x 3 = ( x 1 + x 2 ) / 2 = ( 5 + 7 ) / 2 = 6 x3 = {(x1+x2)}/{2} = (5+7)/2 = 6 x3=(x1+x2)/2=(5+7)/2=6
同理
x 6 = ( x 4 + x 5 ) / 2 = ( 8 + 9 ) / 2 = 8.5 x6 = {(x4+x5)}/{2} = (8+9)/2=8.5 x6=(x4+x5)/2=(8+9)/2=8.5
故插值后,可得

A x1 x2 x3 x4 x5 x6
Value 5 7 6 8 9 8.5

MATLAB程序实现:
(注意:double 类型数据缺失值指示符为NaN)

	A = [5,7,NaN,8,9,NaN] 
	F = fillmissing(A,'movmean',[2,0])

运行结果:
在这里插入图片描述

  有一点需要注意,如果第一个元素为NaN,则无法对其进行插补。
例如:

	A = [NaN,5,7,NaN,8,9,NaN]
	F = fillmissing(A,'movmean',[2,0])

在这里插入图片描述


问:如何用缺失值的前一个值和后一个值的均值进行插补?

MATLAB程序实现:

	A = [5,NaN,7,NaN,3];
	F = fillmissing(A,'movmean',3)

运行结果:
在这里插入图片描述

  道理很简单,分析方法和上文相同,诸君可以试着自己分析一下。


2021年5月18日10:46:15更新


  有的人可能不会加载数据,针对这个问题,我进行了更新,上文中用到的数据源1,在本次更新中会给出。程序运行后,会自动下载数据2,然后读取数据3,最后直接运行出结果。

clear;clc;close all;
%% 下载数据

    api = 'https://archive.ics.uci.edu/ml/machine-learning-databases/00381/';
    url = [api 'PRSA_data_2010.1.1-2014.12.31.csv'];
    filename = 'DataSet.csv';
    options = weboptions('Timeout',Inf); % 将超时值设置为 Inf 以使连接不会超时。
    outfilename = websave(filename,url,options); % 数据下载,保存在DataSet.csv中
%% 读取表格数据

    AllData = readmatrix(filename); 
    pm25data = AllData(25:43824,6); % 读取pm2.5数据
    save("pm25data.mat","pm25data") % 保存数据
%% 加载原始数据  

    load('pm25data.mat')% 原始数据
    figure
    subplot(211)
	t = datetime(2010,1,2,0,0,0) + hours(0:length(pm25data)-1)';% 创建与数据对应的时间向量。
    plot(t,pm25data)% 查看波形
    title('原始数据波形')
    xlabel('Time/h');
    ylabel('PM_{2.5} / (\mu g.m^{-3})');
%% 查找缺失值

    TF1=ismissing(pm25data);% 查找缺失值,TF是逻辑矩阵,利用TF可以找到pm25data内的缺失值
    TF = TF1;
%% 填充缺失值 (pm25dataPre是插补后的数据)

    pm25dataPre = pm25data;
    while max(TF) % 如果还存在缺失值就继续插补
        % pm25data = fillmissing(pm25data,'movmean',30);% 使用窗口长度为 30 的移动均值填充缺失数据。
        pm25dataPre = fillmissing(pm25dataPre,'movmedian',30); % 使用窗口长度为 30 的移动中位数替换数据中的 NaN 值 
        TF=ismissing(pm25dataPre);% 查找数据中的缺失值,TF是逻辑矩阵,利用TF可以找到pm25data内的缺失值
    end
    % plot(TF) % TF中的1对应pm25data中的缺失值,当数据中的缺失值填充完时,可以看到TF的值全为0
    subplot(212)
    plot(t,pm25dataPre,t(TF1),pm25dataPre(TF1),'x')% 查看插补后的数据 pm25dataPre
    title('插补后的数据波形')
    xlabel('Time/h');
    ylabel('PM_{2.5} / (\mu g.m^{-3})');
    legend('原始数据','插补值')
    % save('pm25dataPre.mat','pm25dataPre');% 保存插补后的数据

运行结果:
在这里插入图片描述


2022年10月15日07:25:01更新


  对于新手来说,将数据保存成.mat格式可能有些困难,本次更新教给新手一个手动操作保存数据的方法。该方法适合数据量较少的情况,简单易行。本次更新增加的内容可以概括为三个步骤:创建变量,复制数据,保存数据。

(1)创建变量
① 首先在命令行窗口创建一个空变量pm25data,用于存放数据。

    pm25data = [];

② 在工作区可以看到我们创建的变量pm25data,里面什么数据都没有。
在这里插入图片描述
(2)复制数据
  双击工作区的pm25data变量,如下图①所示,直接将表格中的数据复制到变量中,②中可以看到变量已经有了41757个数据。注意为保证复制成功,请将表格数据中的缺失值指示符全部替换为NaN。

在这里插入图片描述
(3)保存数据
  在命令行窗口利用save保存数据,在当前文件夹窗口可以看到我们保存的数据pm25data.mat。

    save("pm25data.mat","pm25data")

在这里插入图片描述
最后直接运行以下程序即可

clear;clc;close all;
%% 加载原始数据  

    load('pm25data.mat')% 原始数据
    pm25data = pm25data(:);
    subplot(211)
	t = datetime(2010,1,2,0,0,0) + hours(0:length(pm25data)-1)';% 创建与数据对应的时间向量。
    plot(t,pm25data)% 查看波形
    title('原始数据波形')
    xlabel('Time/h');
    ylabel('PM_{2.5} / (\mu g.m^{-3})');
%% 查找缺失值

    TF1=ismissing(pm25data);% 查找缺失值,TF是逻辑矩阵,利用TF可以找到pm25data内的缺失值
    TF = TF1;
%% 填充缺失值 (pm25dataPre是插补后的数据)

    pm25dataPre = pm25data;
    while max(TF) % 如果还存在缺失值就继续插补
        % pm25data = fillmissing(pm25data,'movmean',30);% 使用窗口长度为 30 的移动均值填充缺失数据。
        pm25dataPre = fillmissing(pm25dataPre,'movmedian',30); % 使用窗口长度为 30 的移动中位数替换数据中的 NaN 值 
        TF=ismissing(pm25dataPre);% 查找数据中的缺失值,TF是逻辑矩阵,利用TF可以找到pm25data内的缺失值
    end
    % plot(TF) % TF中的1对应pm25data中的缺失值,当数据中的缺失值填充完时,可以看到TF的值全为0
    subplot(212)
    plot(t,pm25dataPre,t(TF1),pm25dataPre(TF1),'x')% 查看插补后的数据 pm25dataPre
    title('插补后的数据波形')
    xlabel('Time/h');
    ylabel('PM_{2.5} / (\mu g.m^{-3})');
    legend('原始数据','插补值')
    % save('pm25dataPre.mat','pm25dataPre');% 保存插补后的数据

参考资料:


  1. UCI Machine Learning Repository: Data Sets. ↩︎

  2. 将 RESTful Web 服务中的内容保存到文件 - MATLAB websave - MathWorks 中国. ↩︎

  3. 从文件中读取矩阵 - MATLAB readmatrix - MathWorks 中国. ↩︎

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

MATLAB数据预处理之缺失值插补 的相关文章

  • Matlab:如何显示数组的“真实”值?

    我有一个在脚本中计算的向量 计算后 我将值显示到命令窗口 显示如下 finalResults 1 0e 05 0 0001 0 0 0005 0 0002 0 0001 0 0027 0 0033 0 0001 0 0000 0 0000
  • MATLAB中如何画水平线和垂直线?

    我目前正在尝试在 MATLAB 中绘制简单的垂直线和水平线 例如 我想绘制线 y 245 我该怎么做呢 MATLAB 根据您提供的向量逐点进行绘图 因此 要创建一条水平线 您需要改变x同时保持y对于垂直线恒定 反之亦然 xh 0 10 yh
  • Matlab PARFOR 循环可以通过编程方式打开/关闭吗?

    有一个关于 MATLAB 中 parfor 的简单问题 我想在程序中设置一个标志 以便在 parfor 和常规 for 循环之间进行更改 基本上 我需要此功能 以便我的代码的某些部分可以在 调试 模式下更新图形 然后当关闭该标志时 使用 p
  • 检查Matlab中脚本需要使用的函数

    我有一个别人写的代码包 我正在运行一个脚本 它调用一些函数 这些函数又调用更多函数 等等 我想获取不是 MATLAB 内置函数但属于包的一部分的函数列表 我尝试使用matlab codetools requiredFilesAndProdu
  • 不等间隔时间序列的移动平均线

    我有一个证券交易所股票价格的数据集 时间 价格 但数据点之间的间隔并不相等 从 1 到 2 分钟不等 在这种情况下计算移动平均值的最佳实践是什么 如何在Matlab中实现呢 我倾向于认为 点的权重应该取决于自上一个点以来的最后时间间隔 Ma
  • 句柄类和值类的区别

    我有一些 C 背景 想使用 Matlab 中的类 句柄和值类有什么区别 我知道如果我想定义一个带有重载运算符 例如 和 的矩阵类 我会使用值类 然而 有时 当我选择一个手柄类时 事情似乎只对我有用 MathWorks 提供了一些有关其用途的
  • Simulink 仿真引擎如何工作?

    我想了解 Simulink 仿真引擎的工作原理 它是否使用离散事件模拟机制 那么如何处理连续时间 它是否依赖于基于静态循环的代码生成 或者 在第一个周期之前 它会计算出块的执行顺序 从不需要任何其他块输入的块开始 每个周期 它都会根据输入和
  • MATLAB 特征函数

    我很好奇哪里可以找到完整的描述FEATURE功能 它接受哪些论点 没有找到文档 我只听说过memstats and getpid 还要别的吗 gt gt which feature built in undocumented 注意 更完整的
  • 如何告诉 mex 链接到 /usr/lib 中的 libstdc++.so.6 而不是 MATLAB 目录中的 libstdc++.so.6?

    现在 MATLAB 2012a 中的 mex 仅正式支持 gcc 4 4 6 但我想使用 gcc 4 7 风险自负 现在如果我直接用 mex 编译一些东西 它会抱怨 usr lib gcc i686 linux gnu 4 7 cc1plu
  • 如何使用 MATLAB 的 substruct 函数创建表示使用“end”的引用的结构?

    我想使用substruct http www mathworks com help matlab ref substruct html函数创建一个结构体以供使用subsref 目的是使用索引字符串subsref而不是通常的 符号 因为我正在
  • 通过 Matlab 访问 Physionet 的 ptbdb 中的数据库

    我首先设置系统 old path which rdsamp if isempty old path rmpath old path 1 end 8 end wfdb url http physionet org physiotools ma
  • 访问图像的 Windows“标签”元数据字段

    我正在尝试进行一些图像处理 所以现在我正在尝试读取图像 exif 数据 有 2 个内置函数可用于读取图像的 exif 数据 问题是我想读取图像标签 exifread and imfinfo这两个函数都不显示图像标签 Is there any
  • 对数据进行分布拟合 - MATLAB

    我正在尝试对从显微镜图像中收集的一些数据进行分布 我们知道 152 左右的峰值是由于泊松过程造成的 我想将分布拟合到图像中心的大密度 同时忽略高强度数据 我知道如何将正态分布拟合到数据 红色曲线 但它不能很好地捕获右侧的重尾 尽管泊松分布应
  • 如何将复杂的 csv 文件导入到 Matlab 中的数值向量

    我想知道我们应该如何读取由字符串 双精度数和字符等组成的复杂 csv 文件 例如 您能否提供一个可以在此 csv 文件中提取数值的成功命令 Click here http www ecb europa eu stats money yc d
  • Matlab Builder JA - 将 Matlab 编译成 Java jar - 免费版本?

    请记住 我对 Matlab 一无所知 Matlab Builder JA 允许开发人员构建 Matlab 应用程序并将其导出到 Java jar 中 太棒了 我只需要生成一个 jar 然后就可以从其他 java 代码中使用它 有谁知道单罐包
  • MATLAB:在不使用循环的情况下提取矩阵的多个部分

    我有一个巨大的 2D 矩阵 我想从中提取 15 个不同的 100x100 部分 我有两个向量 x 和 y 其中保存了零件的左上角索引 我用过这样的东西 result cam1 x 1 end x 1 end 99 y 1 end y 1 e
  • 检测分段常数信号中的阶跃

    我有一个分段恒定信号 如下所示 我想检测步骤转换的位置 标记为红色 我目前的做法 使用移动平均滤波器平滑信号 http www mathworks com help signal examples signal smoothing html
  • MATLAB 列含义的内存分析

    我正在使用 MATLAB 配置文件来使用命令观察内存 profile memory on profile clear my code profile report and i got this table 1 我想问一下什么意思 已分配内存
  • 读出 Matlab / Octave fft2() 函数输出的特定点

    我正在熟悉 Octave 及其功能fft2 在此玩具示例中 我的目标是生成以下 256 x 256 png 图像的 2D DFT 为了能够轻松理解输出 我尝试将此图像转换为 256 x 256 图像 消除颜色信息 Im imread cir
  • 如何使用SIFT算法计算两幅图像的相似度?

    我已经用过SIFT http en wikipedia org wiki Scale invariant feature transform实施安德里亚 维达尔迪 http www vlfeat org overview sift html

随机推荐