Jus*_*tin 7 matlab interpolation time-series nan
问题:如何在小长度的NaNs上进行局部插值?
我有一个时间序列("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..]
Run Code Online (Sandbox Code Playgroud)
我想在NaN上执行插值.
最基本的方法是从最左边的数据点到最右边的数据点进行线性插值.例如.从x = 10到x = 2的一条线,将从该线分配4个NaN值.
时间序列的长度约为150万,约为10000 NaN,因此我不想合并远离NaN位置的数据(插值).一些NaN的长度为1000-2000.
X(isnan(X)) = interp1(find(~isnan(X)), X(~isnan(X)), find(isnan(X)), 'linear');
Run Code Online (Sandbox Code Playgroud)
将使用整个时间序列在NaN上线性插值.
我如何在本地进行插值?线性应该足够了.也许线性插值在NaN块的左侧和右侧包含几个点(可能是100-200点).自然邻居或样条(?)算法可能更合适; 我必须小心不要在时间序列中添加异常行为(例如,为频率添加虚构的"功率"的插值).
更新:时间序列是一年中一分钟采样温度的记录.线性插值就足够了; 我只需填写~6-7小时的NaN长度间隙(我在NaN间隙之前和NaN间隙之后提供数据).
我认为这(至少部分是)您想要的:
% 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));
Run Code Online (Sandbox Code Playgroud)
请注意,您可以在此处轻松切换插值方法:
% cubic splines
x(nans) = interp1(t(~nans), x(~nans), t(nans), 'spline');
% nearest neighbor
x(nans) = interp1(t(~nans), x(~nans), t(nans), 'nearest');
Run Code Online (Sandbox Code Playgroud)