【问题标题】:Sort the row of one matrix with respect to another matrix对一个矩阵的行相对于另一个矩阵进行排序
【发布时间】:2016-02-25 15:51:43
【问题描述】:

我有两个不同的矩阵AB

A =
  [7 8 9; 
   4 5 6]

B = 
  [22 32 12;
    9  8 10]

sortB = 
      [12 22 32;
        8  9 10]

sortindex_B=[3 1 2;2 1 3];,即12在矩阵B的第三位,22在第一位,32在第二位;第二行类似。

现在我想根据Sortindex_BA 进行排序(即,在矩阵A 中,我希望7 作为第三个元素,8 作为第一个元素,9 作为第一行的第二个元素;类似地对于第二行:第二行为 4,第一行为 5,第三行为 6)。因此结果应如下所示:

A_final =
        [8 9 7;
         5 4 6] 

我怎样才能做到这一点?

【问题讨论】:

    标签: matlab


    【解决方案1】:

    您可以在对B 进行排序时,从sort 命令中请求排序索引矩阵,然后将A 作为一个单元格进行操作,从而使cellfun 可用:

    A = [7 8 9; 4 5 6];
    B = [22 32 12; 9 8 10];
    [sortB, I] = sort(B,2);
    
    Icell = mat2cell(I,ones(1, size(I,1)),size(I,2));
    Acell = mat2cell(A,ones(1, size(I,1)),size(I,2));
    sortA = cell2mat(...
      cellfun(@(x,y) y(x), Icell, Acell, 'UniformOutput', false))
    

    输出(您将第一行输出声明为8 9 7,但您真的是指9 7 8?)

    sortA =
    
         9     7     8
         5     4     6
    

    用于按照您的问题中具体指定的排序;重新映射索引矩阵I:

    A = [7 8 9; 4 5 6];
    B = [22 32 12; 9 8 10];
    [sortB, I] = sort(B,2);
    
    %// re-map I
    for i = 1:size(I,1)
      Itmp = I(i,:);
      for j = 1:size(I,2)
        I(i,Itmp(j)) = j;
      end
    end
    
    Icell = mat2cell(I,ones(1, size(I,1)),size(I,2));
    ImapCell = mat2cell(Imap,ones(1, size(I,1)),size(I,2));
    Acell = mat2cell(A,ones(1, size(I,1)),size(I,2));
    sortA = cell2mat(...
      cellfun(@(x,y) y(x), Icell, Acell, 'UniformOutput', false))
    

    输出

    sortA =
    
         8     9     7
         5     4     6
    

    【讨论】:

    • 感谢您的想法,,,但是我确实有 1000 行 ..但它仍然不适用于第二行,,,有什么想法可以为所有行做吗?跨度>
    • @userss 我有点不确定您正在寻找哪种排序矩阵 A:您是否希望矩阵 A 使用与矩阵 @ 相同的交换操作进行排序987654333@?如果是这样(这将是常见情况),我上面回答中的第一个解决方案就是这样做的。但是,如果您想使用您所描述的 A 的特定排序,我会看看我能做什么,但请注意,排序 执行的交换操作与为 @987654335 执行的交换操作不同@,所以在我继续之前,请确认您确实希望按照描述完成“您的自定义后续排序”。
    • @userss 比较例如原始矩阵中的元素(row,column) = (1,1)A 中的值7B 中的22。但是在您的矩阵A_final 中,值7 对应于(1,3),而sortB 中的值22 对应于(1,2):即,值722 在之后不再“匹配”你的排序算法已经完成:这真的如你所愿吗?
    • @userss Ok 为I 索引矩阵添加了一个重新映射,以便按照您的要求进行排序(这个重新映射可能可以在不使用嵌套 for 循环的情况下以更简洁的方式执行)。
    【解决方案2】:

    使用sort 的组合,如 dfri 的回答和 sub2ind

    A = [7 8 9; 
         4 5 6]; 
    B = [22 32 12;
         9  8  10];
    
    [sortB, sortindex_B] = sort(B,2);
    [~, colIdx] = sort(sortindex_B,2);
    rowIdx = ndgrid(1:size(B,1),1:size(B,2));
    idx = sub2ind(size(B),rowIdx,colIdx);
    sortA = A(idx)
    
    ans =
    
       8   9   7
       5   4   6
    

    【讨论】:

    • 非常简洁漂亮的解决方案
    • 有什么方法可以为多行做吗?
    • 不确定我是否遵循,这适用于任意数量的行
    • 这个结果:sortlA =[9 7 8; 5 4 6],但我想要 [8 9 7 形式的输出; 5 4 6]。因为idx=[3 1 2;2 1 3];,即12在矩阵B的第三位,22在第一,32在第二位。现在我想根据 index_B 对 A 进行排序(即,在矩阵 A 中:我想要 7 作为第三个元素,8 作为第一个元素,9 作为第一行的第二个元素;同样对于第二行:4 在第二个,第一个元素为 5,第三个元素为 6)。因此结果应该看起来像 sortA=[ 8 9 7 ; 5 4 6].
    • @userss 抱歉,我误读了这个问题,现在应该修复。您只需要排序索引的排序索引(即只需再次调用sort
    【解决方案3】:

    您必须使用排序函数返回的索引值逐行执行此操作。

    这样的事情应该可以解决问题,并且可以扩展到矩阵 A 和 B 可能具有的任意数量的行。这也验证了 A 和 B 在继续之前的大小相同。

    B= [22 32 12; 9 8 10]
    A = [7 8 9; 4 5 6];
    assert(all(size(A) == size(B)));
    
    sortB = zeros(size(B));
    finalA= zeros(size(A));
    for i = 1:size(B,1)
        [sorted,idx] = sort(B(i,:));
       sortB(i,:) = sorted;
       tempA = A(i,:);
       tempA = tempA(idx);
       finalA(i,:) = tempA;
    end
    

    【讨论】:

    • 这个结果:finalA 9 7 8 5 4 6
    • 这个结果:finalA =[9 7 8; 5 4 6],但我想要 [8 9 7 形式的输出; 5 4 6]。因为idx=[3 1 2;2 1 3];,即12在矩阵B的第三位,22在第一,32在第二位。现在我想根据 index_B 对 A 进行排序(即,在矩阵 A 中:我想要 7 作为第三个元素,8 作为第一个元素,9 作为第一行的第二个元素;同样对于第二行:4 在第二个,第一个元素为 5,第三个元素为 6)。因此结果应该看起来像 finalA=[ 8 9 7 ; 5 4 6].
    【解决方案4】:

    有很多巧妙的方法可以做到这一点,包括这个for 循环。希望cmets解释一下逻辑。

    clear; %// input the sample data
    A = [7 8 9; 4 5 6];
    B = [22 32 12; 9  8 10];
    sortB =  [12 22 32; 8  9 10];
    
    %// loop through every element in B
    [R C]=size(B);
    for i=1:C
        for j=1:R
        %// Where does A(j,i) need to go in Afinal?
        %// It needs to go in the j-th row, and in
        %// whatever column of B(j,:) equals sortB(j,i).
        Afinal( j , find( B(j,:) ==sortB(j,i)) ) = A(j,i);
        end
    end
    

    结果:

    >> Afinal
    Afinal =
         8     9     7
         5     4     6
    

    【讨论】:

      猜你喜欢
      • 2011-02-10
      • 1970-01-01
      • 2014-07-27
      • 2021-11-09
      • 2019-03-28
      • 1970-01-01
      • 2018-04-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多