Average based on logical mask and condition

I want to average the data according to unique ID and a logical mask. I have 3 km logical mask which will average into perfect 36 km grid. I average into 36 km based on compartmentID I created. I'm having trouble, when I want to discard those 36 km grids when one of the 3 km grid is zero (based on logical mask ID). Size of the matrix is 406, 964 for 36 km grid which perfectly fit 4872, 11568 3 km grids.
%Form the ID's for 3 km grid so to average for 36 km grid.
rowId = ceil( (1 : 4872) / 12 );
colId = ceil( (1 : 11568) / 12 );
[colID, rowID] = meshgrid( colId, rowId );
compartmentID = colID + (rowID - 1) * max(colId);
Average = reshape(accumarray(compartmentID(:),reshape(Grid_3km,[],1), [],@mean,NaN ), 406, 964);
Can anyone help me with the condition, that says if one of the 3 km grid in 36 km is zero then discard the average.

댓글 수: 6

Any diagram, image, or screenshot to help us visualize this?
nlm
nlm 2018년 11월 6일
편집: nlm 2018년 11월 6일
Please find the mat file attached. I need to remove all the compartment ID numbers of 36 km grid even if one of the 3 km grid within 36 km is zero. This is my code. Since there are 144 perfect 3 km grid in a 36 km grid, I wrote this code, it works but very slowly. more than 10 hrs and hasn't finished even one matrix. Unable to attach the file. It is a 4872 by 11568 matrix, it is 12 Mb after zip too. Any idea how I can attach the file? I attached picture of 1) perfect 36 km grid, where repeated numbers represent 3 km grids, 2) imperfect 36 km grid, where zero's indicate missing 3 km grid. I want to remove all the 36 km grids where even one of the 3 km is zero.
Any help is highly appreciated !!!!
x = unique(New_IMERG(1).compartment);
parfor ii=1:size(New_IMERG,1)
for jj=1:size(x,1)
A = sum(New_IMERG(ii).compartment == x(jj),1);
f sum(A) < 144
New_IMERG(ii).compartmentNEW(New_IMERG(ii).compartment==x(jj)) = 0;
end
end
end
you could try make a smaller and more general example... one where you can verify the solution quickly... e.g.
% given a large grid:
a = floor(magic(9)/20);
% find the avg of all possible 3x3 grids which don't contain zeros
one (probably slow) solution to this is:
for i = 1:size(a,1)
for j = 1:size(a,2)
if i+2<=size(a,1) & j+2<=size(a,2)
submat = a(i:i+2,j:j+2);
if any(submat(:)==0)
out(i,j) = nan;
else
out(i,j) = mean(submat(:));
end
end
end
end
disp(out)
but the problem is now easy for others to understand... and all you are looking for now is a faster solution :)
Bruno Luong
Bruno Luong 2018년 11월 6일
편집: Bruno Luong 2018년 11월 6일
"Please find the mat file attached."
Anyone can see it? I don't.
nlm
nlm 2018년 11월 6일
Sorry, I could not attach it. It was larger than 5 Mb.
nlm
nlm 2018년 11월 6일
@JohnGalt Can you please elaborate ?

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

 채택된 답변

Bruno Luong
Bruno Luong 2018년 11월 6일

0 개 추천

Just put NaN on the 3km-grid at the place you want to discard
Grid_3km_Masked = Grid_3km;
Grid_3km_Masked(YourMask==0) = NaN;
then by using your working code on Grid_3km_Masked, it will propagate to the average on coarse-grid data result:
%Form the ID's for 3 km grid so to average for 36 km grid.
rowId = ceil( (1 : 4872) / 12 );
colId = ceil( (1 : 11568) / 12 );
[colID, rowID] = meshgrid( colId, rowId );
compartmentID = colID + (rowID - 1) * max(colId);
Average = reshape(accumarray(compartmentID(:),reshape(Grid_3km_Masked,[],1), [],@mean,NaN ), 406, 964);

댓글 수: 10

nlm
nlm 2018년 11월 6일
This is not working. The average is not right.
Bruno Luong
Bruno Luong 2018년 11월 6일
편집: Bruno Luong 2018년 11월 6일
What you mean by "not right" what do you expect? I just interpret what you ask
"I want to discard those 36 km grids when one of the 3 km grid is zero"
meaning I think you want to completely discard the coarse result when there is one or more of the fine grid data that is/are masked. but might be I don't understood correctly.
nlm
nlm 2018년 11월 6일
You understood it right. When averaging it to coarse resolution the values don't add up right from non-zero 3 km grid to 36 km grid.
Bruno Luong
Bruno Luong 2018년 11월 6일
편집: Bruno Luong 2018년 11월 6일
What you said are actually different to me (so both cannot be right):
  • "I want to discard those 36 km grids" and
  • "don't add up right from non-zero 3 km"
Doesn't mean the same to me. The first one I discard the result the second one I don't count the subpixel fine-gris in the result.
Which one is correct???
For the interpretation of "don't add up"
Grid_3km_Masked = Grid_3km .* (YourMask==1);
rowId = ceil( (1 : 4872) / 12 );
colId = ceil( (1 : 11568) / 12 );
[colID, rowID] = meshgrid( colId, rowId );
compartmentID = colID + (rowID - 1) * max(colId);
Average = accumarray(compartmentID(:),Grid_3km_Masked(:)) ./ ...
accumarray(compartmentID(:),YourMask(:)==1);
Average = reshape(Average,406, 964);
nlm
nlm 2018년 11월 6일
What you said are actually different to me (so both cannot be right):
"I want to discard those 36 km grids" : * YES THIS IS WHAT I WANT to discard those imperfect 36 km grids even if one of the 3 km grid is NaN.
"don't add up right from non-zero 3 km" : Assuming that those imperfect 36 km grids are discarded, the average of remaining 3 km grids (which are within the perfect 36 km) do not average correctly.
Sorry I give up, the more we discuss the more I don't understand what you want.
nlm
nlm 2018년 11월 6일
Sorry, I wasn't clear for you. I figured it out. Slow but works. Thanks everyone !
Do you mind to post the final working version of the code? I'm curious to see what you want to compute.
nlm
nlm 2018년 11월 6일
I got with the code you suggested, I just needed to transpose the matrix. Mask thing did the trick. Thanks.

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

추가 답변 (0개)

카테고리

도움말 센터File Exchange에서 Creating and Concatenating Matrices에 대해 자세히 알아보기

질문:

nlm
2018년 11월 5일

댓글:

nlm
2018년 11월 6일

Community Treasure Hunt

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

Start Hunting!

Translated by