Help : Interpolation missing data

14 views (last 30 days)
Giu Ann
Giu Ann on 23 Mar 2015
Commented: wil on 24 Mar 2015
Hi all,
I am a beginner in Matlab and I tried to interpolate with a polinomial of 3 order a matrix that has a lot of NaN. I tried with the function 'interp1' using cubic but it didn t work.
CS is my matrix (2880,4) I need to interpolate the 2nd 3rd and 4th column. In the first column there is the time sampling. The vector u,v,w have the NaN in the same position. When I have more than one NaN consecutevely (i.e [1 0.1 NaN NaN NaN NaN NaN]) the interpolation computes a wrong data. I tried using different ways (i.e. inpaint_nans and the results are not good).
Could you suggest me something? I am struggling since 3 days with this problems.
(more info: The CS represent a matrix of velocity measurements filtered using a tool that removed the data with bad correlation and signal to noise, unfortunately this program not replace the spike). I attach the data, so you can have a look.
load CS_7_07.txt
u = CS(:,2); v = CS(:,3); w = CS(:,4);
nanx(:,1) = CS(:,1); nanx = isnan(CS(:,2)); t = 1:numel(CS(:,2));
u(nanx) = interp1(t(~nanx), u(~nanx), t(nanx),'linear', 'extrap'); v(nanx) = interp1(t(~nanx), v(~nanx), t(nanx),'linear', 'extrap'); w(nanx) = interp1(t(~nanx), w(~nanx), t(nanx),'linear', 'extrap');
CS = [CS(:,1) u v w];

Answers (3)

wil
wil on 23 Mar 2015
You also overwrite nanx in the line
nanx(:,1) = CS(:,1); nanx = isnan(CS(:,2));
Should this be:
nanu = isnan(CS(:,2));
nanv = isnan(CS(:,3));
nanw = isnan(CS(:,4));
You can also try using the following. The values you are giving it to interpolate onto (t(nanx)) does not contain the full list of values you want to interpolate. If you give it all of t, the values for v(~nanx) will remain the same, and it will interpolate the values in between.
u_n = interp1(t(~nanu), u(~nanu), t,'linear', 'extrap');
v_n = interp1(t(~nanv), v(~nanv), t,'linear', 'extrap');
w_n = interp1(t(~nanw), w(~nanw), t,'linear', 'extrap');
CS(:,2:4) = [u_n v_n w_n];
Hope this helps, Wil

Giu Ann
Giu Ann on 23 Mar 2015
Hi, thank you Will for your reply. Unfortunately, your suggestion hasn't resolved my problem. The last 20 points of the vector u are NaN and the interp1 (as you and I wrote) not gave me the right results. Just to give you a clarification: u is the vector of the first column and the last 71 values are like below: u = [ -0.780 | * |-0.940 * NaN NaN NaN NaN NaN NaN -1.29000000000000 NaN NaN NaN NaN ... NaN NaN]
The results after the interpolation are (u_n):
| -0.780000000000000 -0.940000000000000 | -0.990000000000000 -1.04000000000000 -1.09000000000000 -1.14000000000000 -1.19000000000000 -1.24000000000000 -1.29000000000000 -1.34000000000000 -1.39000000000000 -1.44000000000000 -1.49000000000000 -1.54000000000000 -1.59000000000000 -1.64000000000000 -1.69000000000000 -1.74000000000000 -1.79000000000000 -1.84000000000000 -1.89000000000000 -1.94000000000000 -1.99000000000000 -2.04000000000000 -2.09000000000000 -2.14000000000000 -2.19000000000000 -2.24000000000000 -2.29000000000000 -2.34000000000000 -2.39000000000000 -2.44000000000000 -2.49000000000000 -2.54000000000000 -2.59000000000000 -2.64000000000000 -2.69000000000000 -2.74000000000000 -2.79000000000000 -2.84000000000000 -2.89000000000000 -2.94000000000000 -2.99000000000000 -3.04000000000000 -3.09000000000000 -3.14000000000000 -3.19000000000000 -3.24000000000000 -3.29000000000000 -3.34000000000000 -3.39000000000000 -3.44000000000000 -3.49000000000000 -3.54000000000000 -3.59000000000000 -3.64000000000000 -3.69000000000000 -3.74000000000000 -3.79000000000000 -3.84000000000000 -3.89000000000000 -3.94000000000000 -3.99000000000000 -4.04000000000000 -4.09000000000000 -4.14000000000000 -4.19000000000000 -4.24000000000000 -4.29000000000000 -4.34000000000000 -4.39000000000000 -4.44000000000000 -4.49000000000000 -4.54000000000000 -4.59000000000000 -4.64000000000000 -4.69000000000000 -4.74000000000000 -4.79000000000000 -4.84000000000000 -4.89000000000000 -4.94000000000000 -4.99000000000000 -5.04000000000000 -5.09000000000000 -5.14000000000000 -5.19000000000000 -5.24000000000000 -5.29000000000000 -5.34000000000000 -5.39000000000000 -5.44000000000000 -5.49000000000000 -5.54000000000000 -5.59000000000000 -5.64000000000000 -5.69000000000000 -5.74000000000000 -5.79000000000000 -5.84000000000000 -5.89000000000000 -5.94000000000000 -5.99000000000000 -6.04000000000000 -6.09000000000000 -6.14000000000000 -6.19000000000000 -6.24000000000000 -6.29000000000000 -6.34000000000000 -6.39000000000000 -6.44000000000000 -6.49000000000000 -6.54000000000000 -6.59000000000000 -6.64000000000000 -6.69000000000000 -6.74000000000000 -6.79000000000000 -6.84000000000000 -6.89000000000000 -6.94000000000000 -6.99000000000000 -7.04000000000000 -7.09000000000000 -7.14000000000000 -7.19000000000000 -7.24000000000000 -7.29000000000000 -7.34000000000000 -7.39000000000000 -7.44000000000000 -7.49000000000000
I plot the result and it is like this.
  1 Comment
wil
wil on 24 Mar 2015
If you are trying to extrapolate 71 values from only 3 numeric values, you will find that your extrpolation is very low quality. The extrapolation here is linear, so it will look at the rate of change between the previous values and extrapolate that. Multiply this change by 71 and you have a high number at the end!

Sign in to comment.


John D'Errico
John D'Errico on 23 Mar 2015
Edited: John D'Errico on 23 Mar 2015
The simple answer is just to use my inpaint_nans code, as found on the file exchange.
You need to download it, but it will do the trick with no options needed, replacing ALL NaN elements with interpolated values. Those that must be extrapolated will be extrapolated linearly, really the only safe way to do so.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!