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

1 ビュー (過去 30 日間)
Abigail Morton 2021 年 7 月 29 日

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

サインインしてコメントする。

### 採用された回答

Jan 2021 年 7 月 30 日

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
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 件のコメント表示非表示 なし
Abigail Morton 2021 年 7 月 30 日
Thank you so much for your help, this is an elegant solution!

サインインしてコメントする。

### その他の回答 (2 件)

KSSV 2021 年 7 月 30 日
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 件のコメント表示非表示 1 件の古いコメント
Abigail Morton 2021 年 7 月 30 日
Thanks for the suggestion! As Jan said, I am looking for a code that leaves the long gaps unfilled.

サインインしてコメントする。

Walter Roberson 2021 年 7 月 30 日

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];
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 件のコメント表示非表示 なし
Abigail Morton 2021 年 7 月 30 日
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!

サインインしてコメントする。

R2021a

### Community Treasure Hunt

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

Start Hunting!

Translated by