Нахождение равных строк в Matlab - PullRequest
0 голосов
/ 31 августа 2018

У меня есть матрица suppX в Matlab с размером GxN и матрица A с размером MxN. Я хотел бы, чтобы ваша помощь построить матрицу Xresponse с размером GxM с Xresponse(g,m)=1, если строка A(m,:) равна строке suppX(g,:) и ноль в противном случае.

Позвольте мне объяснить лучше на примере.

suppX=[1 2 3 4; 
       5 6 7 8; 
       9 10 11 12]; %GxN

A=[1 2 3 4; 
   1 2 3 4; 
   9 10 11 12; 
   1 2 3 4]; %MxN

Xresponse=[1 1 0 1; 
           0 0 0 0;
           0 0 1 0]; %GxM

Я написал код, который делает то, что я хочу.

Xresponsemy=zeros(size(suppX,1), size(A,1));
for x=1:size(suppX,1)
    Xresponsemy(x,:)=ismember(A, suppX(x,:), 'rows').'; 
end

Мой код использует цикл. Я хотел бы избежать этого, потому что в моем реальном случае этот кусок кода является частью другого большого цикла. У вас есть предложения без зацикливания?

Ответы [ 2 ]

0 голосов
/ 01 сентября 2018

Вот альтернатива @ ответ rayryeng : уменьшите каждую строку двух матриц до уникального идентификатора, используя третий вывод unique с флагом ввода 'rows', а затем сравните идентификаторы с одноэлементным расширением (широковещанием), используя bsxfun:

[~, ~, w] = unique([A; suppX], 'rows');
Xresponse = bsxfun(@eq, w(1:size(A,1)).', w(size(A,1)+1:end));
0 голосов
/ 31 августа 2018

Один из способов сделать это состоит в том, чтобы рассматривать каждую матрицу как векторы в N мерном пространстве, и вы можете найти норму L 2 (или евклидово расстояние) каждого вектора. После, проверьте, если расстояние равно 0. Если это так, то у вас есть совпадение. В частности, вы можете создать матрицу так, чтобы элемент (i,j) в этой матрице вычислял расстояние между строкой i в одной матрице и строкой j в другой матрице.

Вы можете решить вашу проблему, изменив матрицу расстояний, полученную в результате этой задачи, так что 1 означает, что два вектора полностью одинаковы, а 0 - в противном случае.

Этот пост должен представлять интерес: Эффективно вычислить попарно возведенное в квадрат евклидово расстояние в Matlab .

Я бы специально посмотрел на ответ Шая Багона, который использует матричное умножение и вещание. Затем вы изменили бы его, чтобы найти расстояния, равные 0:

nA = sum(A.^2, 2); % norm of A's elements
nB = sum(suppX.^2, 2); % norm of B's elements
Xresponse = bsxfun(@plus, nB, nA.') - 2 * suppX * A.';
Xresponse = Xresponse == 0;

Получаем:

Xresponse =

  3×4 logical array

   1   1   0   1
   0   0   0   0
   0   0   1   0

Примечание по эффективности с плавающей точкой

Поскольку вы используете ismember в своей реализации, для меня неявно, что вы ожидаете, что все значения будут целочисленными. В этом случае вы можете очень сильно сравнить непосредственно с нулевым расстоянием без потери точности. Если вы намереваетесь перейти к плавающей точке, вы всегда должны сравнивать с небольшим порогом вместо 0, например Xresponse = Xresponse <= 1e-10; или чем-то подобным. Я не верю, что это необходимо для вашего сценария.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...