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

时间:2012-11-19 01:38:37

标签: matlab time-series interpolation nan

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

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

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万~~10000 NaNs,因此我不想合并远离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间隙之后提供数据)。

2 个答案:

答案 0 :(得分:4)

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

% 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');

答案 1 :(得分:3)

考虑使用inpaint_nans,这是一个非常好的工具,用于使用非NaN元素在1维或2维阵列中插入NaN元素。它也可以推断,因为它不使用数据的三角测量。它还允许插值的不同方法。