2016-04-20 5 views
0

Ich habe eine 144x91x92-Matrix in o3{1} gespeichert. Ich möchte über die dritte Dimension (die die Tage in einer Jahreszeit repräsentiert) blicken und sie sortieren. Dann möchte ich die oberen 10 und unteren 10 Prozent der Werte einschließlich des Index dieser Werte herausziehen. Dies würde die oberen 10 und unteren 10 Perzentile von Tagen für jede Gitterzelle finden (dies wäre für jede Gitterzelle unterschiedlich).Sortieren von 3D-Array entlang der 3. Dimension

Ich versuche, die folgenden:

[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);  

Aber ich weiß, ich bin nicht in die Top 10 und unten korrigieren 10. Perzentil ziehen. Außerdem sagt mir dieser Weg nicht die Indizes (unterschiedlich für jede der Rasterzellen 144x91) für das obere und untere 10 Perzentil der Tage. Ich hoffe, mit 144x91x10 Matrizen für die oberen 10 Perzentile der Tage, die unteren 10 Perzentile der Tage und die Indizes für jeden zu enden.

+0

Warum '[Y, I] = sort (o3 {1}, 3);' und nicht '[Y, I] = sort (o3,3);'? Wenn 'o3' eigentlich ein Zellen-Array ist, dann sollten Sie Ihre Frage bearbeiten, um das widerzuspiegeln. – Dan

+0

Ja, ich habe gerade das bearbeitet. o3 ist eine Zelle. o3 {1} ist die 144x91x92 Matrix – shizishan

+0

Gibt es einen Unterschied zwischen 'Y' und' o3_sorted'? Außerdem weißt du, dass wenn du 92 Tage hast, es nur 9 Werte in den oberen und unteren 10 Perzentilen gibt ...? Ich denke, Sie wollen eher 'ind_bot10 = Y (:,:, 1: 9)' ... – Dan

Antwort

1

Probieren Sie es wie folgt aus:

[~, 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) 

Und jetzt

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

Ich habe die anderen Zellen o3 {2}, o3 {3}, etc. Ich möchte die Werte für diejenigen herausholen, so dass sie o3 {1} (Nicht sortieren o3 {2}, o3 {3}, nur herausziehen übereinstimmende Indizes). Wie mache ich das? o3 {i} sind alle gleich groß. – shizishan

+0

Es gibt das Problem, dass ich keine linearen Indizes bin. Ich habe Probleme, es auf die anderen Matrizen anzuwenden. 'ind2sub (Größe (o3 {1}), I)' und 'sub2ind (Größe (o3 {1}), I) funktionieren nicht richtig. – shizishan

+0

@shizishan siehe Bearbeiten – Dan

1

Hier ist eine etwas andere Vorstellung von what Dan had suggested:

%% // 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. 

Diese Lösung möglicherweise nicht für Ihre speziellen Bedürfnisse geeignet sein wie es ist, aber Anpassungen sollten einfach sein. Beachten Sie auch, dass, da genaue Perzentile genommen werden, die Anzahl der Elemente wahrscheinlich zwischen bot10 und top10 abweichen würde.

Kredit für die 3D-Suche geht an Kenneth Eaton/gnovice.

Verwandte Themen