How do I gapfill a vector only if gaps (NaNs) are 10 elements or less?

5 vues (au cours des 30 derniers jours)
Abigail Morton
Abigail Morton le 29 Juil 2021
Modifié(e) : Jan le 1 Août 2021
I have a time-signal that looks something like this:
x=[1,2,3,5,7,9,10,9, NaN,Nan,5,3,2,Nan,Nan,Nan,Nan,Nan,Nan,Nan,Nan,Nan,Nan,Nan,12,13,14,15,16]
I want to use the fillgaps function to fill the gaps in the data. However, for the sake of having a quality signal at the end, I want to make sure that the function only fills gaps up to 10 numbers long. In my example, I would want it to fill the first two NaNs, but not the last 11. I can't seem to find a function in Matlab that does this, how should I do it?
tl;dr: I need to set a limit on the size of gaps that Matlab fills when using the gapfill (or a similar) function

Réponse acceptée

Jan
Jan le 30 Juil 2021
Modifié(e) : Jan le 1 Août 2021
x = [1,2,3,5,7,9,10,9, NaN,NaN,5,3,2,NaN,NaN,NaN,NaN,NaN, ...
NaN,NaN,NaN,NaN,NaN,NaN,12,13,14,15,16];
y = fillgaps(x);
% Find sequences of NaNs longer than 10:
[B, N] = RunLength(isnan(x));
B(B & N < 10) = false; % Exclude short sequences
Mask = RunLength(B, N); % Inflate again
y(Mask) = nan; % Copy original NaNs to output
ax = axes('NextPlot', 'add');
plot(ax, y);
plot(ax, x, 'o');
function [b, n] = RunLength(x, n)
% Cheap and slower version of:
% https://www.mathworks.com/matlabcentral/fileexchange/41813-runlength
if nargin == 1 % Encode: x -> b, n
d = [true; diff(x(:)) ~= 0]; % TRUE if values change
b = x(d); % Elements without repetitions
n = diff(find([d.', true])); % Number of repetitions
else % Decode: b, n -> x
len = length(n); % Number of bins
d = cumsum(n); % Cummulated run lengths
index = zeros(1, d(len)); % Pre-allocate
index(d(1:len-1)+1) = 1; % Get the indices where the value changes
index(1) = 1; % First element is treated as "changed" also
b = x(cumsum(index)); % Cummulated indices
end
end
  1 commentaire
Abigail Morton
Abigail Morton le 30 Juil 2021
Thank you so much for your help, this is an elegant solution!

Connectez-vous pour commenter.

Plus de réponses (2)

KSSV
KSSV le 30 Juil 2021
You can use interp1. Also have a look on fillmissing.
x=[1,2,3,5,7,9,10,9, NaN,NaN,5,3,2,NaN,NaN,NaN,NaN,NaN,NaN,NaN,NaN,NaN,NaN,NaN,12,13,14,15,16] ;
idx = 1:length(x) ;
x_new = x ;
x_new(isnan(x)) = interp1(idx(~isnan(x)),x(~isnan(x)),idx(isnan(x))) ;
plot(idx,x,'*r',idx,x_new,'b')
  2 commentaires
Jan
Jan le 30 Juil 2021
This fills the long gaps also.
Abigail Morton
Abigail Morton le 30 Juil 2021
Thanks for the suggestion! As Jan said, I am looking for a code that leaves the long gaps unfilled.

Connectez-vous pour commenter.


Walter Roberson
Walter Roberson le 30 Juil 2021
Modifié(e) : Walter Roberson le 30 Juil 2021
format short
N = 10;
x = [1,2,3,5,7,9,10,9, NaN,NaN,5,3,2,NaN,NaN,NaN,NaN,NaN,NaN,NaN,NaN,NaN,NaN,NaN,12,13,14,15,16];
mask = isnan(x);
bgstarts = strfind([false mask], [0 ones(1,N)])
bgstarts = 14
bgends = strfind([mask false], [ones(1,N), 0])+N-1
bgends = 24
breakpoints = [1 reshape([bgstarts, bgends+1].',1,[]) length(x)+1]
breakpoints = 1×4
1 14 25 30
pieces = mat2cell(x, 1, diff(breakpoints))
pieces = 1×3 cell array
{[1 2 3 5 7 9 10 9 NaN NaN 5 3 2]} {[NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN]} {[12 13 14 15 16]}
pieces(1:2:end) = cellfun(@fillgaps, pieces(1:2:end), 'uniform', 0)
pieces = 1×3 cell array
{[1 2 3 5 7 9 10 9 5.6452 4.2029 5 3 2]} {[NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN]} {[12 13 14 15 16]}
cell2mat(pieces)
ans = 1×29
1.0000 2.0000 3.0000 5.0000 7.0000 9.0000 10.0000 9.0000 5.6452 4.2029 5.0000 3.0000 2.0000 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 12.0000 13.0000 14.0000 15.0000 16.0000
  1 commentaire
Abigail Morton
Abigail Morton le 30 Juil 2021
Hi Walter,
Thank you for your help! This was how I was thinking of approaching the problem, but I wasn't experienced enough with Matlab to figure out how to do it. I'm going to work through your code and one of the other suggested ones and see which offers the best solution to my problem - thank you for taking the time to help me out!

Connectez-vous pour commenter.

Produits


Version

R2021a

Community Treasure Hunt

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

Start Hunting!

Translated by