MATLAB:使用插值替换缺失值(NaN)

时间:2010-09-02 16:05:22

标签: matlab interpolation nan missing-data

我的单元格数组每个都包含一系列值作为行向量。序列包含由NaN表示的一些缺失值。

我想用某种插值方法替换所有NaN,我怎样才能在MATLAB中做到这一点?我也对如何处理这些缺失值的其他建议持开放态度。

考虑此示例数据来说明问题:

seq = {randn(1,10); randn(1,7); randn(1,8)};
for i=1:numel(seq)
    %# simulate some missing values
    ind = rand( size(seq{i}) ) < 0.2;
    seq{i}(ind) = nan;
end

结果序列:

seq{1}
ans =
     -0.50782     -0.32058          NaN      -3.0292     -0.45701       1.2424          NaN      0.93373          NaN    -0.029006
seq{2}
ans =
      0.18245      -1.5651    -0.084539       1.6039     0.098348     0.041374     -0.73417
seq{3}
ans =
          NaN          NaN      0.42639     -0.37281     -0.23645       2.0237      -2.2584       2.2294

编辑:

根据回复,我认为存在混淆:显然我不使用随机数据,上面显示的代码只是数据结构的一个例子。

实际数据是某种形式的已处理信号。问题是在分析过程中,如果序列包含缺失值,我的解决方案将会失败,因此需要进行过滤/插值(我已经考虑过使用每个序列的平均值来填充空白,但我希望有更强大的功能)

6 个答案:

答案 0 :(得分:8)

好吧,如果您正在使用时间序列数据,那么您可以使用Matlab的内置插值函数。

这样的事情应该适合你的情况,但是你需要稍微量身定做......即。如果您没有等间距采样,则需要修改times行。

nseq = cell(size(seq))
for i = 1:numel(seq)
    times = 1:length(seq{i});
    mask =  ~isnan(seq{i});
    nseq{i} = seq{i};
    nseq{i}(~mask) = interp1(times(mask), seq{i}(mask), times(~mask));

end

您需要使用interp1的选项来确定哪种方法最适合您的情况。

答案 1 :(得分:7)

我会使用inpaint_nans,这是一种用于通过插值替换1维或2维矩阵中的纳米元素的工具。

seq{1} = [-0.50782 -0.32058 NaN -3.0292 -0.45701 1.2424 NaN 0.93373 NaN -0.029006];
seq{2} = [0.18245 -1.5651 -0.084539 1.6039 0.098348 0.041374 -0.73417];
seq{3} = [NaN NaN 0.42639 -0.37281 -0.23645 2.0237];

for i = 1:3
  seq{i} = inpaint_nans(seq{i});
end

seq{:}
ans =
 -0.50782 -0.32058 -2.0724 -3.0292 -0.45701 1.2424 1.4528 0.93373 0.44482 -0.029006

ans =
  0.18245 -1.5651 -0.084539 1.6039 0.098348 0.041374 -0.73417

ans =
  2.0248 1.2256 0.42639 -0.37281 -0.23645 2.0237

答案 2 :(得分:2)

如果您有权访问系统识别工具箱,则可以使用MISDATA功能估算缺失值。根据{{​​3}}:

  

此命令线性插值   估计第一个缺失值   模型。然后,它使用此模型   将丢失的数据估计为   通过最小化输出来参数   预测误差来自于   重建数据。

基本上,算法以类似于期望最大化(EM)算法的方式在估计缺失数据和估计模型之间交替。

估计的模型可以是任何线性模型idmodel(AR / ARX / ..),或者如果未给定,则使用默认顺序状态空间模型。

以下是如何将其应用于您的数据:

for i=1:numel(seq)
    dat = misdata( iddata(seq{i}(:)) );
    seq{i} = dat.OutputData;
end

答案 3 :(得分:1)

使用griddedInterpolant

还有一些其他功能,如interp1。对于曲线图,样条曲线是查找缺失数据的最佳方法。

答案 4 :(得分:0)

正如JudoWill所说,你需要假设你的数据之间存在某种关系。

一个简单的选择是计算整个系列的平均值,并将其用于缺失数据。另一个简单的选择是采用n个前n个值和n个下一个值的平均值。

但要非常小心:如果你缺少数据,你通常会更好地处理那些丢失的数据,而不是弥补一些可能会搞砸你的分析的虚假数据。

答案 5 :(得分:0)

考虑以下示例

X =一些Nx1阵列 Y = F(X),其中含有一些NaN

然后使用

X1 = X(找到(〜isnan(Y))); Y1 = Y(找到(〜isnan(Y)));

现在在X1和Y1上插值以计算所有X的所有值。