Fill in missing NaNs

조회 수: 3 (최근 30일)
Cuong Nguyen
Cuong Nguyen 2020년 3월 30일
댓글: Cuong Nguyen 2020년 3월 31일
I am trying to fill these NaNs following this rule: If there is a single NAN, I want the NAN to be filled in with the average of the numbers before and after. If there is more than one NAN. I want the NAN to be filled in with the nearest number. For example, row 2305 should be the average of 16.3 and 14.8, from 2298 to 2304 should be 16.3, and from 2306 to 2312 should be 14.8.
  댓글 수: 4
Image Analyst
Image Analyst 2020년 3월 30일
Why not use interp1() or regionfill() to linearly interpolate from one side to the other?
Cuong Nguyen
Cuong Nguyen 2020년 3월 30일
I am quite a newbie to matlab, can you make it more specific? Thanks.

댓글을 달려면 로그인하십시오.

채택된 답변

Ameer Hamza
Ameer Hamza 2020년 3월 30일
편집: Ameer Hamza 2020년 3월 30일
Try this:
x = [1;2;3;4;nan;nan;nan;nan;nan;5;7;8;nan;nan;nan;nan;11;11;12;nan;nan;nan;15];
bb = regionprops(isnan(x));
idx_nnan = find(~isnan(x));
idx_nan = find(isnan(x));
[~,idx] = min(abs(idx_nan - idx_nnan'), [], 2);
x(idx_nan) = x(idx_nnan(idx));
a = [bb.Centroid];
a(1:2:end) = [];
bb = bb(a==fix(a));
for i=1:numel(bb)
idx_center = bb(i).Centroid(2);
idx = cumsum(bb(i).BoundingBox([2 4])) + [-0.5 0.5];
x(idx_center) = mean(x(idx));
end
Original x:
x =
1
2
3
4
NaN
NaN
NaN
NaN
NaN
5
7
8
NaN
NaN
NaN
NaN
11
11
12
NaN
NaN
NaN
15
New x:
x =
1.0000
2.0000
3.0000
4.0000
4.0000 % <--- nearesr value
4.0000 % <--- nearesr value
4.5000 % average
5.0000 % <--- nearesr value
5.0000 % <--- nearesr value
5.0000
7.0000
8.0000
8.0000 % <--- nearesr value
8.0000 % <--- nearesr value
11.0000 % <--- nearesr value
11.0000 % <--- nearesr value
11.0000
11.0000
12.0000
12.0000 % <--- nearesr value
13.5000 % average
15.0000 % <--- nearesr value
15.0000
  댓글 수: 4
Cuong Nguyen
Cuong Nguyen 2020년 3월 31일
Oh nice nice. Thank you, I got something to learn from this!
Ameer Hamza
Ameer Hamza 2020년 3월 31일
Glad to be of help.

댓글을 달려면 로그인하십시오.

추가 답변 (2개)

darova
darova 2020년 3월 30일
Use bwlabel
A1 = isnan(A); % find NaN
[L,n] = bwlabel(A1); % label each region
xx = 1:length(A);
for i = 1:n % loop through each region
BW = L==i; % select region
if sum(BW(:))>1 % if more than one 'NaN'
ix1 = find(BW,1,'first'); % first index of region
ix2 = floor(mean(BW.*xx)); % find mean index in region
ix3 = find(B2,1,'last'); % last index of region
A(ix1:ix2) = A(ix1-1); % fill first part
A(ix2+1:ix3) = A(ix3+1); % fill second part
else
ix = find(BW);
A(ix) = mean(A(ix([-1 1]))); % average
end
end
  댓글 수: 1
Cuong Nguyen
Cuong Nguyen 2020년 3월 31일
I tried yours and I got this message "Array indices must be positive integers or logical values". It also shows that the error is in "A(ix) = mean(A(ix([-1 1])))" line.

댓글을 달려면 로그인하십시오.


Andrei Bobrov
Andrei Bobrov 2020년 3월 31일
This question is a repeat of this question:
x = [1;2;3;4;nan;nan;nan;nan;nan;5;7;8;nan;nan;nan;nan;11;11;12;nan;nan;nan;15];
out = [x,f1(x)]
x = [16.3;nan(15,1);14.8];
out = [x, f1(x)]
Here f1:
function out = f1(x)
b1 = fillmissing(x,'linear');
b2 = fillmissing(x,'nearest');
d = [0;diff(bwdist(~isnan(x)),2);0]==-2;
out = b2;
out(d) = b1(d);
end
  댓글 수: 3
Andrei Bobrov
Andrei Bobrov 2020년 3월 31일
No! It only says that this version is available to me :) and this code will work with R2016b and later.
Cuong Nguyen
Cuong Nguyen 2020년 3월 31일
Ahh ok. Can you explain more about this line? It's something about the distance to the edges of NaN cluster I reckon, isn't it?
d = [0;diff(bwdist(~isnan(x)),2);0]==-2;

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 NaNs에 대해 자세히 알아보기

태그

Community Treasure Hunt

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

Start Hunting!

Translated by