interpolate NaNs only if less than 4 consecutive NaNs
8 Ansichten (letzte 30 Tage)
Ältere Kommentare anzeigen
Hello,
I have a vector of datapoints containing some NaNs. I'd like to interpolate the NaNs only if there are 3 or less consecutive NaNs. i.e. interpolate over short datagaps but not long ones.
Any ideas would be welcome. Thanks
6 Kommentare
Akzeptierte Antwort
Jan
am 5 Apr. 2012
Bearbeitet: Jan
am 14 Sep. 2013
% Interpolate all NaN blocks at first:
data = [ 3 4 5 6 NaN 5 4 3 NaN NaN NaN NaN 18 20 21 NaN NaN 24 23];
nanData = isnan(data);
index = 1:numel(data);
data2 = data;
data2(nanData) = interp1(index(~nanData), data(~nanData), index(nanData));
[EDITED, Jan, 15-Sep-2013] The following does not work!
% Clear the long NaN blocks afterwards:
longBlock = strfind(data, NaN(1, 4)); % Does this work?!
index2 = zeros(1, numel(data));
index2(longBlock) = 1;
index2(longBlock + 3) = -1;
index2 = cumsum(index2);
data2(index2(1:numel(data)) ~= 0) = NaN; % Catch trailing NaNs
2 Kommentare
Karolina
am 13 Sep. 2013
I'm trying to apply this for an array, where I only interpolate over values that have 4 or less NaNs in a single column. Any idea how to do that?
Jan
am 14 Sep. 2013
Bearbeitet: Jan
am 14 Sep. 2013
@Karolina: The original question has been "interpolate if I have 3 or less NaNs". Your question is "interpolate if I have 4 or less NaNs". The required changes to my code are tiny and trivial. Did you try it already?
What did you observe?
longBlock = strfind(data, NaN(1, 4))
This does not work. After the OP has accepted the answer, I did not check this anymore.
Weitere Antworten (1)
Geoff
am 4 Apr. 2012
Okay, here's a fun way to find the long sequences. You could interpolate the entire lot and then set the long sequences back to NaN. I'm using regexp because it's powerful =)
n = reshape(isnan(x), numel(x), 1); % ensure row-vector
[a, b] = regexp( char(n+'A'), 'B{4,}', 'start', 'end' );
This does string matching on sequences of 'B' (NaN) that are 4 characters or longer, and returns their start and end indices into the vectors a and b.
The nice thing about this is you can mess around with the regular expression to detect exactly what you want.
For example, to get only the indices of sequences with 3 or less NaNs, incorporating the non-NaN on either side, you would use:
'AB{1,3}A'
What you do with the indices is up to you.
2 Kommentare
Jan
am 12 Apr. 2012
The reshaping of x can be simplified: "n = x(:)". Although I confuse this frequently, I think that this is a column vector, not a row vector.
The REGEXP method is nice. +1
It should be possible to use "conv(isnan(x), ones(1,4))" also.
Geoff
am 12 Apr. 2012
Oh yeah, I didn't think of just doing:
n = isnan(x(:));
I thought at the time: "okay I want isnan(x)(:) but I can't do that!"
Duhhh. =)
Siehe auch
Kategorien
Mehr zu Logical finden Sie in Help Center und File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!