问题:如何在小长度的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间隙之后提供数据)。
答案 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元素。它也可以推断,因为它不使用数据的三角测量。它还允许插值的不同方法。