relabel the elements in each column according to the magnitude of these elements in an array

Hi, I have
a=[4 5;
5 1;
6 4;
7 7]
I want to relabel the elements in each column according to the magnitude of these elements in the column to become
a=[1 3;
2 1;
3 2;
4 4]
How can I do this? Thank you.

 Accepted Answer

This works:
a=[4 5; 5 1;6 4; 7 7]
[as,ai] = sort(a,1);
b = [ai(ai(:,1),1) ai(ai(:,2),2)]
produces:
b =
1 3
2 1
3 2
4 4
It sorts the first and second columns independently. Then, to get the column indices as you want them, it maps each set of column indices to its own sorted indices. A bit complicated to explain, but taking the reference to the columns of b apart and looking at its components will reveal how it works.

12 Comments

Hi Star,
as gives me the sorted array for the first and second column independently.
What is ai? I can't figure it out.
Here I've found it:
as=sorted array in ascending order
ai=position of the index
But Star, this can't apply to other arrays? For example:
d=[6 4;
4 5;
2 6;
7 7]
Relabel, and I want to get
e=[3 1;
2 2;
1 3;
4 4]
If I used the code that u suggested,
[as,ai] = sort(d,1);
e = [ai(ai(:,1),1) ai(ai(:,2),2)]
gives me
e=[1 1;
2 2;
3 3;
4 4]
What's the problem? Did I misunderstand something? Thank you.
This works for both, plus some test matrices I created:
m = a; % Define ‘argument’ matrix
ms = sort(m,1); % Sort
for k1 = 1:size(m,2) % Column iterations
for k2 = 1:ize(m,1) % Row iterations
mi(k2,k1) = find(m(k2,k1) == ms(:,k1));
end
end
The ‘mi’ matrix is the matrix of indices that maps column sort order to position in the argument matrix.
Not quite as compact, but reasonably fast.
Hi Star, I put my a and d in a big array,f which gives me:
f=
[4x2 double]
[4x2 double]
I want to run the code above in a time, then I did:
[r c]=size(f);
for col=1:c
for row=1:r
ff{row,col}=sort{f{row,col,1) % To sort the two arrays in f and denote the sorted arrays as ff
end
end
[rr cc]=size(f{r,c}); % to find the size for each array in f
for col=1:c
for row=1:r
for di=1:cc
for mi=1:rr
fff{utr,utc}(rr,cc)=find(f{utr,utc}(rr,cc)==ff{utr,utc}(:,cc));
end
end
end
end
I can't get what i want in the end, what mistakes did i make in the code above?
My code was predicated on the elements in each row being unique with no repeats. If there are repeats, the code will fail. I didn’t anticipate that, since it wasn’t part of the original problem. I’ll see what I can do to make it work with repeats, since I understand how it works, but no promises. (I created the new array out of vertically concatenating ‘a’ and ‘d’.)
I can’t follow your code by inspection, and there are some obvious typos (probably inadvertent in pasting it to the Comment window) so I can’t run it.
Apologise for the delay. It took a while to figure it out, but it turned out to be a surprisingly easy solution, using only a bulit-in MATLAB functon and one small loop:
a=[4 5; 5 1;6 4; 7 7];
d=[6 4;
4 5;
2 6;
7 7];
g = [a; d];
m = g; % Define ‘argument’ matrix
for k1 = 1:size(m,2)
[mu(:,k1) ai(:,k1) mui(:,k1)] = unique(m(:,k1));
end
result = mui
The ‘result’ array should be what you want.
Really thanks a lot, Star :) This helps me a lot!! Thanks again!!
My pleasure!
It’s an unusual enough request that it took some time to come up with solution. When I was Answering another Question involving unique, it occurred to me that the unique function actually does exactly what you want.

Sign in to comment.

More Answers (0)

Categories

Community Treasure Hunt

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

Start Hunting!