首页 文章

MATLAB对2D和3D矩阵进行排序并通过索引进行访问

提问于
浏览
4

我们说你有一个矩阵

a = rand(1,5);
[sa i] = sort(a);

那么 saa(i) 是一样的 . 但是,如果矩阵的大小增加

a = rand(3,4);
[sa i] = sort(a);

然后 saa(i) 是不一样的 . 当我尝试按照第三维对3D矩阵进行排序时,也会发生同样的情况 .

如何通过索引 i 访问 a 的值?或者换句话说,如何计算 sa=a(X)X 应该是什么?

Edit:

谢谢你的解决方案 . 但是,当您更改要排序的维度时,它们不起作用 . 不过,我接受了这个想法并用它来构建一般形式 .

算法正在做的是构建矩阵的索引 . MATLAB逐列索引单元格 . 因此,索引由下式给出

idx = r + (c-1)*ROWS + (p-1)*ROWS*COLS

其中, idx 是索引, r 是行位置, c 是列位置, p 是页面位置 .

因此,如果我们在第一维(正常 sort(a) )中排序,结果索引就是列中的位置;如果我们在第二维中排序,结果索引就是行中的位置;如果我们在第三维中排序,结果索引就是页面位置 . 这就是说,它只能为给定的情况生成行和列:

r = repmat((1:rows)',[1 cols pages]);
c = repmat(1:cols,[rows 1 pages]);

在给出的解决方案中解释了第一维中的排序 . 然后,让我们在二维数组的第二维(行方向)中排序

a = rand(4,5);
[rows cols pages] = size(a);
R = repmat((1:rows)',[1 cols pages]);
[sa idx] = sort(a,2);
nIdx = R + (idx-1)*rows;
isequal(sa,a(nIdx))

现在,如果我们在第三维(页面方式)中使用相同的想法进行排序,我们需要这样做

a = rand(4,5,3);
[rows cols pages] = size(a);
R = repmat((1:rows)',[1 cols pages]);
C = repmat(1:cols,[rows 1 pages]);
[sa idx] = sort(a,3);
nIdx = R + (C-1)*rows + (idx-1)*rows*cols;
isequal(sa,a(nIdx))

并且可以使用相同的逻辑将其扩展到N维 . 感谢您的帮助,您点亮了道路 . :)

4 回答

  • 1
    a = rand(3,5);
    [sa i] = sort(a);
    ii=bsxfun(@plus,i,0:size(a,1):numel(a)-size(a,1));
    isequal(a(ii),sa)
    
  • 4

    从这里:http://www.mathworks.com/help/techdoc/ref/sort.html

    sa(:,j) = a(i(:,j),j)
    
  • 1

    [sa, i]=sort(a) 返回每列的有序索引 . 您只需要获得矩阵的正确线性指数 . 那么,对于2D矩阵,

    A=rand(3,4);
    [rows,cols]=size(A);
    [B,index]=sort(A,1);
    correctedIndex=index+repmat(0:cols-1,rows,1)*rows;
    

    现在测试一下:

    A =
    
        0.9572    0.1419    0.7922    0.0357
        0.4854    0.4218    0.9595    0.8491
        0.8003    0.9157    0.6557    0.9340
    
    B =
    
        0.4854    0.1419    0.6557    0.0357
        0.8003    0.4218    0.7922    0.8491
        0.9572    0.9157    0.9595    0.9340
    
    A(correctedIndex)
    
    ans =
    
        0.4854    0.1419    0.6557    0.0357
        0.8003    0.4218    0.7922    0.8491
        0.9572    0.9157    0.9595    0.9340
    
  • 0

    您可以使用IND2SUBSUB2IND函数创建适用于任何N-D矩阵或排序维度的通用矢量化解法 . 在这里,我将这个解决方案打包成一个新函数 sort_linear_index ,它的行为就像SORT函数一样,只不过它将返回线性索引,这样无论 A 是什么大小,_534512都会一直工作 .

    function [sortedA,sortIndex] = sort_linear_index(A,sortDim,sortOrder)
    %#SORT_LINEAR_INDEX   Just like SORT, but returns linear indices
    
      sizeA = size(A);  %# Get the matrix size
      if nargin < 2
        sortDim = find(sizeA > 1,1);  %# Define sortDim, if necessary
      end
      if nargin < 3
        sortOrder = 'ascend';  %# Define sortOrder, if necessary
      end
      [sortedA,sortIndex] = sort(A,sortDim,sortOrder);  %# Sort the matrix
      [subIndex{1:numel(sizeA)}] = ...  %# Create a set of matrix subscripts
         ind2sub(sizeA,reshape(1:prod(sizeA),sizeA));
      subIndex{sortDim} = sortIndex;  %# Overwrite part of the subscripts with
                                      %#   the sort indices
      sortIndex = sub2ind(sizeA,subIndex{:});  %# Find the linear indices
    
    end
    

    现在我们可以测试一下这个功能了:

    >> A = rand(1,10);
    >> [B,IX] = sort_linear_index(A);  %# Sort a row vector
    >> isequal(B,A(IX))
    ans =
         1
    >> A = rand(3,4,3);
    >> [B,IX] = sort_linear_index(A,1);  %# Sort a 3-by-4-by-3 matrix along
    >> isequal(B,A(IX))                  %#   the first dimension
    ans =
         1
    >> [B,IX] = sort_linear_index(A,3);  %# Sort a 3-by-4-by-3 matrix along
    >> isequal(B,A(IX))                  %#   the third dimension
    ans =
         1
    >> [B,IX] = sort_linear_index(A,2,'descend');  %# Sort a 3-by-4-by-3 matrix along
    >> isequal(B,A(IX))                            %#   the second dimension
    ans =                                          %#   in descending order
         1
    

相关问题