MATLAB: Interpolation over NaNs in a time series
interpolation, matlab, nan, time-series
Solution
I think this is (at least partially) what you seek:
% 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));
note that you can easily switch interpolation method here:
% cubic splines
x(nans) = interp1(t(~nans), x(~nans), t(nans), 'spline');
% nearest neighbor
x(nans) = interp1(t(~nans), x(~nans), t(nans), 'nearest');
Problem
Question: How to locally interpolate over small lengths of NaNs? I have a time series ("x" data sampled evenly at "t" times) that has blocks of NaNs. For example: ``` 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..] ``` I want to perform interpolation over the NaN. The most elementary approach would be to just linearly interpolate from the left-most data point to the right-most data point. Eg. a line from x = 10 to x = 2 and the 4 NaN values will be assigned values from the line. The length of the time series is ~1.5 million with ~10000 NaNs, so I don't want to incorporate data (in the interpolation) that is far away from the NaN locations. Some of the NaNs span a length of 1000-2000. ``` X(isnan(X)) = interp1(find(~isnan(X)), X(~isnan(X)), find(isnan(X)), 'linear'); ``` will linearly interpolate over the NaN using the whole time series. How would I interpolate locally? Linear should be sufficient. Perhaps linear interpolation incorporating a few points to the left and to the right of the NaN blocks (maybe 100-200 points). A natural neighbour or spline (?) algorithm might be more suitable; I must be careful in not adding anomalous behaviour to the time series (e.g. interpolation that adds fictitious "power" to a frequency). UPDATE: The time series is a record of a minute-sampled temperature over a year long period. Linear interpolation is sufficient; I just need to fill in the ~6-7 hour length gaps of NaNs (I am provided with data before the NaN gaps and after the NaN gaps).