MATLAB:在时间序列中对 NaN 进行插值

Posted

技术标签:

【中文标题】MATLAB:在时间序列中对 NaN 进行插值【英文标题】:MATLAB: Interpolation over NaNs in a time series 【发布时间】:2012-11-06 22:48:18 【问题描述】:

问题:如何在小长度的 NaN 上进行局部插值?

我有一个包含 NaN 块的时间序列(“x”数据在“t”时间均匀采样)。 例如:

x = [ 1   2   4    2 3 15 10 NaN NaN NaN NaN 2 4 NaN 19 25]
t = [0.1 0.2 0.3 ...etc..]

我想对 NaN 执行插值。

最基本的方法是从最左边的数据点线性插值到最右边的数据点。例如。从 x = 10 到 x = 2 的一行,4 个 NaN 值将从该行分配值。

时间序列的长度约为 150 万,NaN 约为 10000,因此我不想合并远离 NaN 位置的数据(在插值中)。一些 NaN 的长度为 1000-2000。

X(isnan(X)) = interp1(find(~isnan(X)), X(~isnan(X)), find(isnan(X)), 'linear'); 

将使用整个时间序列对 NaN 进行线性插值。

我将如何在本地进行插值?线性应该足够了。也许线性插值在 NaN 块的左侧和右侧合并了几个点(可能是 100-200 点)。自然邻居或样条(?)算法可能更合适;我必须小心不要在时间序列中添加异常行为(例如,将虚构的“功率”添加到频率的插值)。

更新: 时间序列是在长达一年的时间内对分钟采样温度的记录。线性插值就足够了;我只需要填写大约 6-7 小时的 NaN 间隔(在 NaN 间隔之前和 NaN 间隔之后向我提供了数据)。

【问题讨论】:

线性插值只使用与被插值区域相邻的值,因此无需担心“使用整个时间序列”。还是问题表现? 我真傻。我的印象是它使用最小二乘线性拟合,然后使用拟合分配点。如果 interp1 'linear' 只是连接相邻的左右点并进行插值,那么 'cubic' 和 'pchip' 有什么区别?例如。它不适合数据的三次方然后插值? 你在问什么是最好的插值方法?如果是这样,那么最好的方法实际上取决于您的应用程序。例如,对于某些应用程序,您可能只想使用过去的数据进行插值,因为线性插值之类的方法意味着您提前知道下一个非 NaN 观测值将是什么。在频谱的另一端,您可以应用 EM 算法,该算法将缺失的观测值替换为其有条件的期望值,条件是每个其他观测值的联合分布。因此,在不了解您的应用程序的情况下很难回答。 @JustinChiu:三次拟合样条曲线,它使用被插值区域两侧的两个数据点来定义两者之间的曲线。 【参考方案1】:

我认为这(至少部分)是您所寻求的:

% example data
x = [ 1   2   4    2 3 15 10 NaN NaN NaN NaN 2 4 NaN 19 25];
t = linspace(0.1, 10, numel(x));

% indices to NaN values in x 
% (assumes there are no NaNs in t)
nans = isnan(x);

% replace all NaNs in x with linearly interpolated values
x(nans) = interp1(t(~nans), x(~nans), t(nans));

请注意,您可以在这里轻松切换插值方法:

% cubic splines
x(nans) = interp1(t(~nans), x(~nans), t(nans), 'spline');

% nearest neighbor
x(nans) = interp1(t(~nans), x(~nans), t(nans), 'nearest');

【讨论】:

【参考方案2】:

考虑使用inpaint_nans,这是一个非常好的工具,旨在使用非 NaN 元素在 1-d 或 2-d 数组中插入 NaN 元素。它也可以推断,因为它不使用数据的三角剖分。它还允许不同的插值方法。

【讨论】:

以上是关于MATLAB:在时间序列中对 NaN 进行插值的主要内容,如果未能解决你的问题,请参考以下文章

matlab 如何用插值给NAN赋值

matlab 如何用插值给NAN赋值

Matlab三次样条法插值

matlab里答案出现NaN是啥情况

Matlab中非Nan-Sparse变换马赛克图像的有效混合

在 C++ 中对插值坐标进行排序和搜索