Azzera filtri
Azzera filtri

How can I sort the output matrix according to the prescribed order in a column?

2 visualizzazioni (ultimi 30 giorni)
Hi all,
I have my output matrix data in nx3 dimension.
Now I wish to sort these data,neither in the ascending nor descending order in a column, but according to the prescribed order in a column.
For example, if my matrix is
1 0.5 0.8
10 0.6 0.5
11 0.3 0.1
13 0.1 0.8
Now I want to sort the matrix according to the prescribed order of "11 10 1 13" in column 1, that is, the sorted matrix is expected to be
11 0.3 0.1
10 0.6 0.5
1 0.5 0.8
13 0.1 0.8
What is your suggestion?
Thanks in advance.
Fei

Risposte (2)

dpb
dpb il 6 Lug 2013
Modificato: dpb il 7 Lug 2013
Presuming you have (or can generate) the desired order vector, then it's pretty much trivial--just find where they're located in the original array. This assumes no ties.
Mat
>> ix=[11 10 1 13]';
%
%[erratum -- dpb]
% following returns the locations in the index vector, NOT in the array
>> [~,ib]=ismember(M(:,1),ix); % INCORRECT original posting
%
% It was intended to interchange the order of arguments as follows
>> [~,ib]=ismember(ix,M(:,1)); % CORRECT
%[ end erratum]
>> M(ib,:)
ans =
11.0000 0.3000 0.1000
10.0000 0.6000 0.5000
1.0000 0.5000 0.8000
13.0000 0.1000 0.8000
>>
  2 Commenti
Fei
Fei il 7 Lug 2013
Thanks dpb.
This works efficiently, however I think there might be an error in your code.
[~,ib]=ismember(M(:,1),ix)
returns ib which is the location of M(:,1) found in ix, e.g., '1' is in ix(3), therefore you have ib=3; then you output M(3,:) as the first row but this is not logical because no one tells us M(3,:) should be in the first row, although the final result is right by chance.
Now suppose I add a 5th row in my original matrix, say the matrix is
1 0.5 0.8
10 0.6 0.5
11 0.3 0.1
13 0.1 0.8
9 0 15
Now I wish to output in the order like [[11 9 10 1 13], using the code above will yield
13.0000 0.1000 0.8000
11.0000 0.3000 0.1000
1.0000 0.5000 0.8000
9.0000 0 15.0000
10.0000 0.6000 0.5000
I think the right one is
[~,ib]=ismember(ix,M(:,1))
We output the location of ix found in M(:,1), and then sequentially print the data according to the location. For instance, '11' should be in the first row according to the prescribed order, and it is M(3:1), therefore we have ib=3 and print M(3,:) in the first row.
M=[1 0.5 0.8
10 0.6 0.5
11 0.3 0.1
13 0.1 0.8
9 0 15];
ix=[11 9 10 1 13];
[lia,locb]=ismember(ix,M(:,1))
M(locb,:)
output is
lia =
1 1 1 1 1
locb =
3 5 2 1 4
ans =
11.0000 0.3000 0.1000
9.0000 0 15.0000
10.0000 0.6000 0.5000
1.0000 0.5000 0.8000
13.0000 0.1000 0.8000
dpb
dpb il 7 Lug 2013
_This works efficiently, however I think there might be an error in your code.
[~,ib]=ismember(M(:,1),ix)
...the right one is
[~,ib]=ismember(ix,M(:,1)) _
That is correct, sorry--I did inadvertently swap the order of which is in which in the argument list and by chance the original sample case didn't show it up...

Accedi per commentare.


Andrei Bobrov
Andrei Bobrov il 7 Lug 2013
Modificato: Andrei Bobrov il 8 Lug 2013
a = [1 0.5 0.8
10 0.6 0.5
11 0.3 0.1
13 0.1 0.8
9 0 15];
b = [11 9 10 1 13];
[~,ia] = sort(a(:,1));
[~,ib] = sort(b);
out = a(ia(ib),:);
ADD
[~,ia] = sort(a(:,1));
[~,ib] = sort(b);
ii = sortrows([ia(:),ib(:)],2);
out = a(ii(:,1),:);
  2 Commenti
Fei
Fei il 8 Lug 2013
Thank you Andrei.
This seems working well also. However I don't understand why
a = [1 0.5 0.8
10 0.6 0.5
11 0.3 0.1
13 0.1 0.8
9 0 15];
[~,ia] = sort(a(:,1))
would give
ia =
1
5
2
3
4

Accedi per commentare.

Categorie

Scopri di più su Shifting and Sorting Matrices in Help Center e File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by