【问题标题】:Mapping ids of two vectors映射两个向量的 id
【发布时间】:2014-02-14 20:06:07
【问题描述】:

我有两个具有相同元素的向量,但它们的顺序不同。例如

一个

10
9 
8

B

8
9
10

我想找到两者之间的映射

B2A

3
2
1

如何在 matlab 中有效地做到这一点?

【问题讨论】:

    标签: matlab


    【解决方案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 表示该方法,但我认为您的第三行 sort 错误。也许你得到的是“A2B”而不是B2A。看我的回答
    • 我猜这个问题的定义并不清楚,因为两者是相同的。我将其定义为满足 'isequal(A,B(B2A))' 的向量
    【解决方案2】:

    有几种方法可以做到这一点。就代码行而言,最有效的可能是使用ismember()。返回值为[Lia,Locb] = ismember(A,B),其中LocbB 中的索引,对应于A 的元素。你可以[~, B2A] = ismember(A, B) 得到你想要的结果。如果您的 MATLAB 版本不允许 ~,请为第一个输出提供一次性参数。

    您必须确保存在一对一的映射才能获得有意义的结果,否则索引将始终指向第一个匹配的元素。

    【讨论】:

    • 我不同意。这是第二个输出参数,而不是第一个。请仔细阅读
    【解决方案3】:

    这里有一个解决方案:

    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
    

    【讨论】:

    • @MadPhysicist 你能解释一下原因吗?因为从我的角度来看,它给出了很好的结果......
    • 发帖者要求效率。 find 一开始效率不高,对每个元素运行它也无济于事。
    • @MadPhysicist ismember 使用 find 函数。
    【解决方案4】:

    我会使用三个链接的sort's 来选择Joe Serrano's answer

    另一种方法是使用bsxfun 测试所有组合是否相等:

    [~, B2A] = max(bsxfun(@eq, B(:), A(:).'));
    

    这给出了B2A,使得B(B2A) 等于A。如果您希望反过来(从您的示例中不清楚),只需在 bsxfun 内反转 AB

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-06-02
      • 2021-10-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-17
      相关资源
      最近更新 更多