Find the first element that satisfies a condition on 3D data

I'm trying to use a logical expression to find the first instance of a condition being met on a 3d matrix.
I have this dummy code for a 1d array that works the way it should:
d = randi([0 50], 100, 1);
dd = sort(d, 'descend');
pa = sum(dd);
dc = cumsum(dd);
%find row where cumsum is 50% of sum
g = find(dc >0.5*pa,1);
However, I can't get it to work on my 3d data of longitude, latitude and time (360,150,365). I want to find the n'th timestep (in the third dimension) where SC is equal to or greater than 1/2 of the sum at each latitude-longitude pair and write that to a new matrix (2d, 360X150). My current attemp is as follows:
prec = ncread(filename_p, 'Prec_gs'); % 360x150x365 matrix
p_annual(:,:) = sum(prec,3,'omitnan'); % 360x150 matrix
S = sort(prec,3,'descend'); % 360x150x365 matrix
SC = cumsum(S,3); % 360x150x365 matrix
N50(:,:) = find(SC(:,:,:) >= 0.5.*p_annual(:,:), 1);
The last row isn't working because the the dimensions are not the same (3d vs 2d), I have tried making p_annual a 3d matrix of same size as SC but still no luck.
Any thoughts on how to solve this?

댓글 수: 2

An example of your data input and expected output would be helpful.
I have attached a sample data file (20x30x365).
Code to open/read the file:
filename = 'GLDAS_cropped.nc';
ncid = netcdf.open(filename);
prec = ncread(filename, 'precipitation');
I expect to get a 20x30 matrix with the element (a number between 1 and 365) where SC is equal to or greater than 50% of p_annual. Thanks for your help.

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

 채택된 답변

Matt J
Matt J 2021년 5월 24일
S = sort(prec,3,'descend'); % 360x150x365 matrix
SC = cumsum(S,3,'omitnan'); % 360x150x365 matrix
p_annual = SC(:,:,end);
[~,N50] = max(SC >= 0.5.*p_annual,[], 3);

댓글 수: 6

This gives me the same issue I had before, dimensions not matching.
I don't see any evidence of a problem:
load precipitation.mat
S = sort(prec,3,'descend'); % 360x150x365 matrix
SC = cumsum(S,3,'omitnan'); % 360x150x365 matrix
p_annual = SC(:,:,end);
[~,N50] = max(SC >= 0.5.*p_annual,[], 3);
whos
Name Size Bytes Class Attributes N50 20x30 4800 double S 20x30x365 1752000 double SC 20x30x365 1752000 double ans 1x42 84 char p_annual 20x30 4800 double prec 20x30x365 1752000 double
Interesting, I get the following error:
Error using >=
Number of array dimensions must match for binary array op.
I'm using R2016a, I will try a different version and see if it helps.
The code assumes R2016b or higher. I do recommend upgrading, but if you can't then you can make this modification instead,
[~,N50] = max( bsxfun(@ge, SC, 0.5.*p_annual) ,[], 3);
Yep, that works, thank you so much!
To get it right, I needed to put NaN values last when sorting, but otherwise works like a charm!
S = sort(prec,3,'descend','MissingPlacement','Last');

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

추가 답변 (0개)

카테고리

도움말 센터File Exchange에서 Logical에 대해 자세히 알아보기

질문:

2021년 5월 24일

댓글:

2021년 5월 25일

Community Treasure Hunt

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

Start Hunting!

Translated by