How can I use a for loop to interpolate to a certain number of points, and remove NaNs?

10 views (last 30 days)
I have a for-loop to remove NaN values at the end of my dataset, and this currently interpolates to the longest trial in my dataset:
[Ny,Nx] = size(sr_norm);
Nz = sum(~isnan(sr_norm));
for k = 1:Nx
sr_interp(:,k) = interp1(1:Nz(k),sr_norm(1:Nz(k),k),1:Ny,'linear','extrap'); %Remove NaN at the end
I am trying to interpolate the data set to 360 points, so that for every 1 that pr_transpose increases, we can see what the increase in sr_transpose is. Each dataset is longer than 360 points. I have been able to do this after removing the NaN values by repeating for each trial number as below:
ParticipantNo_1_S = [sr1; sr2; sr3; sr4; sr5];
This I know is really clunky, but I have not been able to figure out how to incorporate them together. Any thoughts and ideas would be much appreciated!
pkll201 on 2 May 2023
Sorry, I wasn't clear! Yes I am hoping to avoid using numbered variables for the second part - and if I can incorporate that into the first part (but I am not sure that I will be able to get that to work so I think these may have to stay as separate sections!)

Sign in to comment.

Accepted Answer

Rik on 2 May 2023
Edited: Rik on 2 May 2023
For the second part it is easy enough with a few cell vectors as an intermediate step (if you want to store the separate elements). I'm not sure I understand the first section well enough to suggest how to merge the two sections.
for n=1:size(pr_transpose1,1)
ParticipantData = vertcat(sr{:});

More Answers (1)

dpb on 2 May 2023
Edited: dpb on 2 May 2023
Like @Rik, I don't understand the desire well enough to know precisely the result you're looking for, but to find the locations of the NaN in the original array and interpolate it to the range 0:360 based on length of each finite segment in each column is straightforward enough with the help of arrayfun to walk through the columns of the array. Explicit for loops can be used as well, of course, this done here for pedagogical reasons as much as anything, just to illustrate...
load sample_data
whos % see what is in the .mat file
Name Size Bytes Class Attributes ans 1x40 80 char cmdout 1x33 66 char pr_transpose1 5x643 25720 double sr_norm 643x5 25720 double
iz=arrayfun(@(c)find(isfinite(sr_norm(:,c)),1,'last'),1:size(sr_norm,2),'uni',1) % find the end finite location
iz = 1×5
459 612 643 604 592
xq=[0:360].'; % the interpolated points (NB: is 361 points, not 360)
ans = 1×2
361 5
[p(1:5,:);p(357:end,:)] % show first, last few columns result
ans = 10×5
0 0 0 0 0 1 0 0 0 0 2 1 0 1 0 3 1 0 1 0 4 2 0 1 1 261 207 201 204 243 262 207 202 205 243 263 208 202 206 244 263 209 203 206 245 264 210 203 207 246
The interpolation goes from 0:N-1 to avoid the initial NaN and need for the 'extrap' flag; then just use the row lengths determined from the find operation. Using isnan there returns the location past the last finite location; you can use that but then the one column (third, I think it is) is full length and returns empty for that column; that then takes more code to fixup that location. Finding the last finite location in each column instead keeps everything bounded.
As noted, I don't really follow what the actual end result wanted here is, but that should give pointers on at least one way to do the interpolation. Another choice if happen to have the Signal Processing TB would be resample although there are also versions for the timeseries which won't help much here without a time vector although one could create an artificial one. I've found the timeseries of limited use although I'm sure there are places/applications it would work out just fine; it's never seemed to fit the specific things I've ever tried to do when I have poked at it...


Find more on Loops and Conditional Statements in Help Center and File Exchange




Community Treasure Hunt

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

Start Hunting!