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 commentaires

Any diagram, image, or screenshot to help us visualize this?
nlm
nlm le 6 Nov 2018
Modifié(e) : nlm le 6 Nov 2018
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 le 6 Nov 2018
Modifié(e) : Bruno Luong le 6 Nov 2018
"Please find the mat file attached."
Anyone can see it? I don't.
nlm
nlm le 6 Nov 2018
Sorry, I could not attach it. It was larger than 5 Mb.
nlm
nlm le 6 Nov 2018
@JohnGalt Can you please elaborate ?

Connectez-vous pour commenter.

 Réponse acceptée

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 commentaires

nlm
nlm le 6 Nov 2018
This is not working. The average is not right.
Bruno Luong
Bruno Luong le 6 Nov 2018
Modifié(e) : Bruno Luong le 6 Nov 2018
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 le 6 Nov 2018
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 le 6 Nov 2018
Modifié(e) : Bruno Luong le 6 Nov 2018
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 le 6 Nov 2018
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.
Bruno Luong
Bruno Luong le 6 Nov 2018
Sorry I give up, the more we discuss the more I don't understand what you want.
nlm
nlm le 6 Nov 2018
Sorry, I wasn't clear for you. I figured it out. Slow but works. Thanks everyone !
Bruno Luong
Bruno Luong le 6 Nov 2018
Do you mind to post the final working version of the code? I'm curious to see what you want to compute.
nlm
nlm le 6 Nov 2018
I got with the code you suggested, I just needed to transpose the matrix. Mask thing did the trick. Thanks.

Connectez-vous pour commenter.

Plus de réponses (0)

Catégories

Community Treasure Hunt

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

Start Hunting!

Translated by