2016-12-07 2 views
2

Скажет, у меня есть вектор A идентификаторов элементов:Как отсортировать столбцы матрицы в порядке очередного вектора в MATLAB?

A=[50936 
    332680 
    107430 
    167940 
    185820 
    99732 
    198490 
    201250 
    27626 
    69375]; 

И у меня есть матрица B строка которой содержит значение 8 параметров для каждого из элементов в векторе A:

B=[0 0 0 0 0 0 0 0 0 0 
    0 0 0 0 0 0 0 0 0 0 
    1 0 1 0 0 1 0 1 1 1 
    1 0 1 0 0 1 0 1 1 1 
    0 0 1 0 0 0 0 1 0 1 
    0 0 0 0 0 0 0 1 0 0 
    0 0 0 0 0 0 0 0 0 0 
    0 0 0 0 0 0 0 0 0 1]; 

Так, столбец 1 в матрице B представляет данные элемента в строке 1 вектора A, столбец 2 в матрице B представляет данные элемента в строке 2 вектора A и т. д. Тем не менее, я хочу матрицу B содержать информацию, в другом порядке вещей, хранящуюся в векторе A2:

A2=[185820 
    198490 
    69375 
    167940 
    99732 
    332680 
    27626 
    107430 
    50936 
    201250]; 

Как сортировать их, так что столбец 1 матрицу B содержит данные для элемента в строке 1 вектор A2, столбец 2 матрицы B содержит данные для элемента в строке 2 вектора A2 и т. Д.?

Моего очень сырое решение, чтобы сделать это следующим образом:

A=A'; A2=A2'; 

for i=1:size(A,2) 
    A(2:size(B,1)+1,i)=B(:,i); 
end 

A2(2:size(B,1)+1,:)=zeros(size(B,1),size(B,2)); 

for i=size(A2,2) 
    for j=size(A,2) 
     if A2(1,i)==A(1,j) 
      A2(2:end,i)=A(2:end,j); 
     end 
    end 
end 

B2 = A2(2:end,:); 

Но я хотел бы знать, уборщик, более элегантные и меньше времени метод потребления, чтобы сделать это.

ответ

6

Возможное решение

Вы можете использовать второй выход ismember функции.

[~ ,idx] = ismember(A2,A); 
B2 = B(:,idx); 

Update: Я проверил, как мое решение и другие предложенного hbaderts

disp('-----ISMEMBER:-------') 
tic 
    [~,idx]=ismember(A2,A); 
toc 
disp('-----SORT:-----------') 
tic 
    [~,idx1] = sort(A); 
    [~,idx2] = sort(A2); 
    map = zeros(1,size(idx2)); 
    map(idx2) = idx1; 
toc 

Вот результат в октаве:

-----ISMEMBER:------- 
Elapsed time is 0.00157714 seconds. 
-----SORT:----------- 
Elapsed time is 4.41074e-05 seconds. 

Заключение: рода метод более эффективен т!

+1

Whoa! Это тоже очень крутое решение. Четкий, лаконичный и точный. Как в стороне, как вы помните, сколько выходов выполняют все эти многочисленные функции? И что еще более важно, как вы помните о них в нужный момент? :) – Kristada673

+1

, прежде чем я увидел его в документации. однако перед тем, как ответить на вопрос, я использовал «help ismember» в командной строке и перепроверял документацию! – rahnema1

+0

@ Kristada673 ответ обновлен, вы можете принять другой ответ! – rahnema1

0
[A2, sort_order] = sort(A); 
B2 = B(:, sort_order) 

Функция сортировки MATLAB возвращает порядок сортировки элементов в A. Вы можете использовать это, чтобы заказать столбцы в B.

+0

Но это отсортирует идентификаторы предметов в порядке возрастания и сохранит их в 'A2'. Это не то, что я хочу сделать. У меня уже есть 'A2' в каком-то значимом предопределенном порядке. – Kristada673

4

В обоих A и A2 содержат те же самые элементы, просто отсортированы по-разному, мы можем создать отображение из A -sorting к A2 -sorting. Для этого мы запускаем функцию sort на обоих и сохраняем индексы (которые являются вторым выходом).

[~,idx1] = sort(A); 
[~,idx2] = sort(A2); 

Теперь, первый элемент в idx1 соответствует первому элементу в idx2, поэтому A(idx1(1)) такое же, как A2(idx2(1)) (который 27626). Для того, чтобы создать отображение idx1 -> idx2, мы используем матрицу индексацию следующим

map = zeros(size(idx2)); 
map(idx2) = idx1; 

Для сортировки B соответственно, все, что нам нужно сделать, это

B2 = B(:, map); 
+0

Это очень крутое решение. Благодарю. – Kristada673

0

Транспонирование B так что вы можете сцепить его с A:

C = [A B'] 

Теперь у вас есть

C = [ 50936 0 0 1 1 0 0 0 0; 
    332680 0 0 0 0 0 0 0 0; 
    107430 0 0 1 1 1 0 0 0; 
    167940 0 0 0 0 0 0 0 0; 
    185820 0 0 0 0 0 0 0 0; 
     99732 0 0 1 1 0 0 0 0; 
    198490 0 0 0 0 0 0 0 0; 
    201250 0 0 1 1 1 1 0 0; 
     27626 0 0 1 1 0 0 0 0; 
     69375 0 0 1 1 1 0 0 1]; 

Теперь вы можете отсортировать строки матрицы, как хотите.Например, для сортировки по ID в порядке возрастания, используйте sortrows:

C = sortrows(C) 

Чтобы просто поменять строки вокруг, использовать перестановку 1:length(A):

C = C(perm, :) 

где perm может быть что-то вроде [4 5 6 3 2 1 8 7 9 10].

Таким образом, вся ваша информация содержится в одной структуре, и данные всегда правильно сопоставляются с соответствующим идентификатором.

Смежные вопросы