Сортировка матрицы по порядку, указанному во второй матрице (MATLAB) - PullRequest
6 голосов
/ 12 августа 2011

У меня есть bigmatrix, который отсортирован.Однако мне нужно изменить порядок в соответствии с порядком идентификаторов в другой матрице (col. 1 here for both matrices).Как я могу сделать это с помощью векторизации?Например:

bigmat = [ ...
            1 10 ; 
            1 30 ; 
            1 40 ; 
            2 1  ; 
            2 11 ; 
            3 58 ; 
            4 2  ;
            4 5 ] ;

ordermat = [ 2 ; 1 ; 4 ; 3 ; 6] ;       % Integer IDs

finalans = [ ...
            2 1  ; 
            2 11 ; 
            1 10 ; 
            1 30 ; 
            1 40 ;
            4 2  ;
            4 5  ;
            3 58 ; ] ;

Возможно, что все некоторые идентификаторы (здесь целые числа) в ordermat могут отсутствовать в bigmat.Их можно игнорировать, как показано выше с помощью id = 6.Спасибо!

Ответы [ 3 ]

2 голосов
/ 12 августа 2011

Вот мое решение:

ordermat = [2; 1; 4; 3; 6];
bigmat = [
    1 10
    1 30
    1 40
    2 1
    2 11
    3 58
    4 2
    4 5
];
%#bigmat = sortrows(bigmat,1);

%# keep valid IDs, 
ord = ordermat( ismember(ordermat,bigmat(:,1)) );
ord = grp2idx(ord);

%# starting/ending locations of the different IDs in bigmat
startInd = find( diff([0;bigmat(:,1)]) );
endInd = [startInd(2:end)-1; size(bigmat,1)];

%# generate startInd(i):endInd(i) intervals
ind = arrayfun(@colon, startInd, endInd, 'UniformOutput',false);

%# order then combine the intervals of indices
ind = [ind{ord}];

%# get final sorted result
finalans = bigmat(ind,:);

Я убедился, что он обрабатывает различные случаи, такие как:

  • ordermat содержит идентификаторы, не найденные в bigmat: ordermat = [2;1;4;3;6]
  • не все идентификаторы bigmat представлены в ordermat: ordermat = [2;1]
  • Идентификаторы не последовательные и / или не начинаются с 1: ordermat=ordermat+10; bigmat=bigmat+10;
1 голос
/ 12 августа 2011
%# Input values:
bigmat = [1 10; 1 30; 1 40; 2 1; 2 11; 3 58;  4 2; 4 5];
ordermat = [ 2 ; 1 ; 4 ; 3 ; 6] ;   

%# Make a look-up table that tells us the relative order for each order id
sortmat(ordermat) = 1:length(ordermat);

%# Extract the order ID's from the big matrix
keys = bigmat(:,1);

%# Get the new ordering
new_key = sortmat(keys);

%# Sort the new ordering, remembering the permutation necessary
[~, permutation] = sort(new_key);

%# Apply the permutation to the big matrix
finalans = bigmat(permutation, :);
0 голосов
/ 12 августа 2011

Я бы разделил bigmat на куски в соответствии с уникальными идентификаторами, а затем переупорядочил куски следующим образом:

%# this assumes bigmat is sorted, btw
%# i.e. that the different ids are grouped together

%# find unique ids
dd = [true;diff(bigmat(:,1))~=0];

uniqueIDs = bigmat(dd,1);

%# reorder uniqueIDs
[~,newOrder] = ismember(uniqueIDs,ordermat);

%# if there are uniqueIDs that are not in ordermat
%# we'd need to remove those. I assume this won't
%# be the case

%# chop up bigmat
numUniqueIds = diff([find(dd);length(dd)+1]);
bigChunks = mat2cell(bigmat,numUniqueIds,size(bigmat,2));

%# reorder chunks
finalans = cat(1,bigChunks{newOrder});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...