Reputation: 2036
I have two vectors with the same elements but their order is not same. For eg
A
10
9
8
B
8
9
10
I want to find the mapping between the two
B2A
3
2
1
How can I do this in matlab efficiently?
Upvotes: 1
Views: 110
Reputation: 112749
I would go for Joe Serrano's answer using three chained sort'
s.
Another approach is to test all combinations for equality with bsxfun
:
[~, B2A] = max(bsxfun(@eq, B(:), A(:).'));
This gives B2A
such that B(B2A)
equals A
. If you want it the other way around (not clear from your example), simply reverse A
and B
within bsxfun
.
Upvotes: 0
Reputation: 424
I think the Matlab sort is efficient. So:
[~,I]=sort(A); %sort A; we want the indices, not the values
[~,J]=sort(B); %same with B
%I(1) and J(1) both point to the smallest value, and a similar statement is true
%for other pairs, even with repeated values.
%Now, find the index vector that sorts I
[~,K]=sort(I);
%if K(1) is k, then A(k) is the kth smallest entry in A, and the kth smallest
%entry in B is J(k)
%so B2A(1)=J(k)=J(K(1)), where BSA is the desired permutation vector
% A similar statement holds for the other entries
%so finally
B2A=J(K);
if the above were in script "findB2A" the following should be a check for it
N=1e4;
M=100;
A=floor(M*rand(1,N));
[~,I]=sort(rand(1,N));
B=A(I);
findB2A;
all(A==B(B2A))
Upvotes: 1
Reputation: 3204
Here a solution :
arrayfun(@(x)find(x == B), A)
I tried with bigger arrays :
A = [ 7 5 2 9 1];
B = [ 1 9 7 5 2];
It gives the following result :
ans =
3 4 5 2 1
Edit
Because arrayfun
is usually slower than the equivalent loop, here a solution with a loop:
T = length(A);
B2A = zeros(1, length(A));
for tt = 1:T
B2A(1, tt) = find(A(tt) == B);
end
Upvotes: 0
Reputation: 114440
There are a couple of ways of doing this. The most efficient in terms of lines of code is probably using ismember()
. The return values are [Lia,Locb] = ismember(A,B)
, where Locb
are the indices in B
which correspond to the elements of A
. You can do [~, B2A] = ismember(A, B)
to get the result you want. If your version of MATLAB does not allow ~
, supply a throwaway argument for the first output.
You must ensure that there is a 1-to-1 mapping to get meaningful results, otherwise the index will always point to the first matching element.
Upvotes: 0