Fill NaN cell with mean of eight surrounding cells in grid data in matlab

조회 수: 3 (최근 30일)
Shakir Hussain
Shakir Hussain 2018년 4월 21일
편집: Jan 2018년 4월 25일
I am trying to fill the NaN values of grid data with 8 surrounding values but could not understand, what is going wrong here in my matlab code. The data is 752*891*11 %%% (11 years precipitation of 752*891 cells).
for i = 2 : 752
for j = 2 : 891
for k = 1 : 11
if isnan(data(i,j,k)) == 1
data(i,j,k) = nanmean(nanmean(data(i-2:i+2,j-2:j+2,k-2:k+2)));
end
end
end
end
Thanks in advance for help

채택된 답변

Jan
Jan 2018년 4월 21일
편집: Jan 2018년 4월 25일

If you want to replace a scalar based on a 3D array, you either need 3 nanmean calls:

nanmean(nanmean(nanmean(data(i-1:i+1, j-1:j+1, k-1:k+1))))

with i-1:i+1, instead of i-2:i+2. This would be easier:

if isnan(data(i,j,k))   % "== 1" is not needed
  tmp         = data(i-1:i+1, j-1:j+1, k-1:k+1);  % 3D block
  data(i,j,k) = nanmean(tmp(:));                  % Make it a vector
end

But this is a 3x3x3 neighborhood with 27 elements, not 8. I assume you mean:

if isnan(data(i,j,k))   % "== 1" is not needed
  tmp1        = data(i-1:i+1, j, k);
  tmp2        = data(i:i, j-1:j+1, k);
  tmp3        = data(i, j, k-1:k+1);
  tmp         = [tmp1(:); tmp2(:); tmp3(:)];  % Create a vector
  data(i,j,k) = nanmean(tmp);
end

Because the center point data(i,j,k) is included 3 times, but ignored by nanmean, you have 6 neighbors now, not 8.

So please explain again, what you exactly want.

  댓글 수: 7
Jan
Jan 2018년 4월 24일
편집: Jan 2018년 4월 24일

When you access the index i-2:i+2, the loop for i must start at 3, not at 2, because 0 is not a valid index. And the loop must stop at size(data, 1) - 2. Equivalently for j.

Please post a copy of the complete message, if you mention an error in the forum.

Shakir Hussain
Shakir Hussain 2018년 4월 25일
Thank you jan The problem has solved

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

추가 답변 (1개)

Walter Roberson
Walter Roberson 2018년 4월 22일
means = conv2(YourMatrix, [1 1 1;1 0 1;1 1 1]/8,'same') ;
mask = isnan(YourMatrix);
YourMatrix(mask) = means(mask);

No loops needed.

Note: you would need a little adjustment to handle a nan on the edge of the matrix, to calculate the means properly.

  댓글 수: 4
Jan
Jan 2018년 4월 22일

A solution to use conv2 with NaNs:

nanX    = isnan(X);
X(nanX) = 0;
mask    = [1 1 1; 1 0 1; 1 1 1];
means   = conv2(X,     mask, 'same') ./ ...
          conv2(~nanX, mask, 'same');
X(nanX) = means(nanX);

But I'm not sure, how this can be applied to the OP's problem. A neighborhood of 6 or 10(?) elements is wanted.

Image Analyst
Image Analyst 2018년 4월 23일
Just change the mask shape and elements to be whatever is wanted.

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

카테고리

Help CenterFile Exchange에서 Interpolation of 2-D Selections in 3-D Grids에 대해 자세히 알아보기

태그

Community Treasure Hunt

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

Start Hunting!

Translated by