2016-09-07 2 views
1

У меня есть переменная матрица:Как найти строки и столбцы в MATLAB

A = [1  2  8  8  1 
    4  6  8  1  1 
    5  3  1  1  8]; 

и у меня есть переменная B:

B=[2 3 1 8 8]; 

Вопрос заключается в том, чтобы найти строки и столбцы (сортировка по строкам) в переменной A из переменной B.

Пример: первый индекс в переменной B равен 2, а затем я хочу найти значение 2 в переменной A и перейти к первым строкам и столбцам, а следующий процесс - до индекса 5, но если строки и столбцы был использован так, чтобы получить вторая позиция (напр. индекс 4 & 5 с одинаковым значением).

rows; 
columns; 

Результат:

rows = 1 3 1 1 1 
columns = 2 2 1 3 4 

ответ

0

Использование можно использовать найти и sub2ind добиться того, что вы хотите , но для этого вы должны принять транспонировать из ваших Первый

A = [1  2  8  8  1 
    4  6  8  1  1 
    5  3  1  1  8]; 
B= [2 3 1 8 8]; 
TMP = A.'; 
for i = 1:length(B) 
    indx = find(TMP== B(i),1,'first') %Finding the element of B present in A 
    if(~isempty(indx)) % If B(i) is a member of A 
     [column(i),row(i)] = ind2sub(size(TMP),indx) % store it in row and column matrix 
     TMP(indx) = nan; % remove that element 
    end 
end 

column =

2  2  1  3  4 

строка =

1  3  1  1  1 

Как и в одном из комментариев Usama предложенных предраспределения памяти вы можете сделать это с помощью

row = zeros(1,sum(ismember(B,A))) 
column= zeros(1,sum(ismember(B,A))) 

Приведенный выше код работает даже если есть некоторые элементы из B, отсутствующие в A

+0

Недостатком этого решения является то, что вы меняете матрицу A. – NLindros

+0

Вы можете сохранить ее в некоторой матрице Temp – Umar

+0

Не знаю, если это полезно для OP, но если одно значение B больше максимального значения A, ваш код сработает – obchardon

0

Использование find. Функция может возвращать как линейный индекс, так и индекс row/col.

Используя линейный индекс решение может быть

idx = zeros(size(B)); 
for i = 1:numel(B) 
    % Find all indexes 
    tmpIdx = find(A == B(i)); 
    % Remove those already used 
    tmpIdx = setdiff(tmpIdx, idx); 
    % Get the first new unique 
    idx(i) = tmpIdx(1); 
end 
% Convert index to row and col 
[rows, cols] = ind2sub(size(A),idx) 

Отдает:

rows = 1 3 1 1 2 
cols = 2 2 1 3 3 

Обратите внимание, что, как линейная индексация идет вниз столбец по столбцам, результат здесь отличается от того, в вашем примере (хотя и по-прежнему правильный индекс)

rows = 1 3 1 1 1 
columns= 2 2 1 3 4 

Но для этого вы могли бы просто транспонировать e A (A.') и переверните строки и столбцы (результат от ind2sub)

+0

@ Sardar_Usama Ах, да, правильно. Но для не сложной матрицы/массива они одинаковы? Или это другая разница, о которой я не знаю? – NLindros

+0

Это потому, что сопряжение действительного числа - это то же самое число! Итак, вы можете сказать, что функциональность такая же, но если вы заявляете, что «A» является транспозицией, тогда это утверждение неверно! –

0

Здесь находится решение, в котором я использую цикл, я попытался оптимизировать количество итераций и вычислительную стоимость. Если между B и A нет соответствующего значения, индекс строки/столбца возвращает NaN.

[Bu,~,ord] = unique(B,'stable'); 

% Index of each different values 
[col,row] = arrayfun(@(x) find(A'==x),Bu,'UniformOutput',0) 

% For each value in vector B we search the first "non already used" corresponding value in A. 
for i = 1:length(B) 
    if ~isempty(row{ord(i)}) 
     r(i) = row{ord(i)}(1); 
     row{ord(i)}(1) = []; 
     c(i) = col{ord(i)}(1); 
     col{ord(i)}(1) = []; 
    else 
     r(i) = NaN; 
     c(i) = NaN; 
    end 
end 

РЕЗУЛЬТАТ:

c = [2 2 1 3 4] 

r = [1 3 1 1 1] 
+0

Рассмотрите предварительную выделение памяти для 'r' и' c', так как это не считается практикой хорошего программирования для увеличения размера вектора в цикле. Для справки прочтите следующее: http://www.mathworks.com/help/matlab/matlab_prog/preallocating-arrays.html Ваше решение работает, хотя :-) –

+1

@Sardar_Usama невозможно предварительно выделить 'col' и' row 'поскольку выходной сигнал не является однородным. Но да, возможно создать 'c = нули (длина (B), 1);' – obchardon

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