简体   繁体   English

沿3维对3D数组排序

[英]Sorting 3D array along 3rd dimension

I have a 144x91x92 matrix stored in o3{1} . 我有一个144x91x92矩阵存储在o3{1} I'd like to look across the third dimension (representing the days in one season) and sort it. 我想浏览第三个维度(代表一个季节中的天数)并对其进行排序。 Then, I want to pull out the top 10 and bottom 10 percentile of values including the index of those values. 然后,我想提取值的前10个百分位数和后10个百分位数,包括这些值的索引。 This would find the top 10 and bottom 10 percentile of days for each grid cell (this would be different for each grid cell). 这将找到每个网格单元的前10天和最后10%天(每个网格单元会有所不同)。

I'm trying the following: 我正在尝试以下方法:

[Y,I] = sort(o3{1},3); % sort o3 along 3rd dimension
o3_sorted = o3{1}(I);
ind_top10 = o3_sorted(90);
ind_bot10 = o3_sorted(10);    

But I know I'm not pulling out the top 10 and bottom 10th percentile correct. 但是我知道我并没有提出正确的前10个百分点和前10个百分点。 Plus, this way does not tell me the indices (different for each of the 144x91 grid cells) for the top and bottom 10 percentile of days. 另外,这种方式不会告诉我前10天和下10天百分位的索引(每个144x91网格单元的索引不同)。 I am hoping to end up with 144x91x10 matrices for the top 10 percentile of days, the bottom 10 percentile of days, and the indices for each. 我希望最终得到144x91x10矩阵,以表示前10%的天数,后10%的天数以及每个索引。

Try it like this: 像这样尝试:

[~, I] = sort(o3{1},3); %// sort o3 along 3rd dimension
ind_top10 = I(:,:,end-8:end);
ind_bot10 = I(:,:,1:9);

I3 = cat(3, ind_top10, ind_bot10); %// you might want to skip this but and just work with the top and bottom separately from here on

[I1, I2, ~] = ndgrid(1:size(o3{1},1), 1:size(o3{1},2), 1:size(I3,3));
ind = sub2ind(size(o3{1}),I1,I2,I3)

And now 现在

o3{2}(ind)
o3{3}(ind)
%// etc...

Here's a slightly different idea from what Dan had suggested : 这与Dan提出的想法略有不同:

%% // Init
clear variables; clc;

%% // Generate some data:
o3 = cell(3,1);
for indO = 1:3
  o3{indO} = randi(intmax('uint16'),144,91,92,'uint16');
end

%% // Find 10 & 90 percentiles:
percentiles = cat(3,prctile(o3{1},10,3),prctile(o3{1},90,3));

%% // Find indices of relevant values
select_bot10 = bsxfun(@ge,o3{1},percentiles(:,:,1)); %// replace @ge with @gt if needed
select_top10 = bsxfun(@le,o3{1},percentiles(:,:,2)); %// replace @le with @lt if needed
%// Another optional way to index the values if required:
[rb,cb,vb] = ind2sub(size(select_bot10),find(select_bot10));
[rt,ct,vt] = ind2sub(size(select_top10),find(select_top10));

%% // Get values from o3{1..3} etc.
bot10 = o3{1}(select_bot10);
top10 = o3{1}(select_top10);
%// etc.

This solution might not be suitable for your specific needs as it is, but adaptations should be straightforward. 此解决方案可能不适合您的特定需求,但改编应该很简单。 Also note that since exact percentiles are taken, the number of elements would probably differ between bot10 and top10 . 还要注意,由于采用了精确的百分位数,因此bot10top10之间的元素数量可能会有所不同。

Credit for the 3D find goes to Kenneth Eaton / gnovice . 3D查找的功劳归功于 Kenneth Eaton / gnogno

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM