我有两个具有相同元素的向量,但它们的顺序不相同。例如
A
10
9
8
乙
8
9
10
我想找到两者之间的映射
B2A
3
2
1
如何有效地在matlab中执行此操作?
答案 0 :(得分:1)
我认为Matlab排序很有效。所以:
[~,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);
如果以上是脚本“findB2A”,则以下内容应该是检查
N=1e4;
M=100;
A=floor(M*rand(1,N));
[~,I]=sort(rand(1,N));
B=A(I);
findB2A;
all(A==B(B2A))
答案 1 :(得分:0)
这是一个解决方案:
arrayfun(@(x)find(x == B), A)
我尝试使用更大的数组:
A = [ 7 5 2 9 1];
B = [ 1 9 7 5 2];
它给出了以下结果:
ans =
3 4 5 2 1
修改强>
因为arrayfun
通常比等效循环慢,所以这里是一个带循环的解决方案:
T = length(A);
B2A = zeros(1, length(A));
for tt = 1:T
B2A(1, tt) = find(A(tt) == B);
end
答案 2 :(得分:0)
有几种方法可以做到这一点。在代码行方面最有效的可能是使用ismember()
。返回值为[Lia,Locb] = ismember(A,B)
,其中Locb
是B
中与A
元素对应的索引。您可以[~, B2A] = ismember(A, B)
获得所需的结果。如果您的MATLAB版本不允许~
,请为第一个输出提供一次性参数。
您必须确保存在1对1映射才能获得有意义的结果,否则索引将始终指向第一个匹配元素。
答案 3 :(得分:0)
我会使用三个sort'
s来Joe Serrano's answer。
另一种方法是使用bsxfun
测试所有组合是否相等:
[~, B2A] = max(bsxfun(@eq, B(:), A(:).'));
这会B2A
,B(B2A)
等于A
。如果你想要反过来(从你的例子中不清楚),只需在A
内反转B
和bsxfun
。