在两个Matlab矩阵之间找到相等的行

时间:2018-10-03 10:12:40

标签: matlab performance matrix rows set-intersection

我在Matlab中有一个大小为index的矩阵GxN和一个大小为A的矩阵MxN

在提出问题之前,让我提供一个例子。

clear
N=3;
G=2;
M=5;

index=[1  2  3;
       13 14 15]; %GxN

A=[1  2  3; 
   5  6  7; 
   21 22 23; 
   1  2  3;
   13 14 15]; %MxN

如果行Response等于GxM,如果行Response(g,m)=1等于A(m,:),我想请您帮忙用index(g,:)构造大小为Response= [1 0 0 1 0; 0 0 0 0 1]; %GxM 的矩阵Response=permute(any(all(bsxfun(@eq, reshape(index.', N, [], G), permute(A, [2 3 4 1])), 1), 2), [3 4 1 2]);

继续上面的示例

N=19, M=500, G=524288

这段代码可以满足我的要求(取自previous question of mine-只是为了澄清:当前的问题有所不同)

SSRS

但是,对于我的实际矩阵大小(2008R2),该命令非常慢。我知道我将无法获得巨大的速度,但是对此有任何改进的建议。

3 个答案:

答案 0 :(得分:7)

MATLAB具有working with sets的多种功能,包括setdiffintersectunion等。在这种情况下,您可以使用ismember函数:

[~, Loc] = ismember(A,index,'rows');

哪个给:

Loc =
     1
     0
     0
     1
     2

Response的构造如下:

Response = (1:size(index,1) == Loc).';

Response =
  2×5 logical array
   1   0   0   1   0
   0   0   0   0   1

答案 1 :(得分:7)

方法1:计算距离

如果您具有统计信息工具箱:

Response = ~(pdist2(index, A));

或:

Response = ~(pdist2(index, A, 'hamming'));

之所以可行,是因为pdist2计算每对行之间的距离。相等的行的距离为0。逻辑否定~为这些行对给出1,否则为0

方法2:将行减少为唯一的整数标签

这种方法在我的机器上更快:

[~,~,u] = unique([index; A], 'rows');
Response = bsxfun(@eq, u(1:G), u(G+1:end).');

通过将行简化为唯一的整数标签(使用unique的第三个输出),然后比较后者而不是前者来进行工作。

对于您的尺寸值,这在我的计算机上大约需要1秒钟:

clear
N = 19; M = 500; G = 524288;
index = randi(5,G,N); A = randi(5,M,N);
tic
[~,~,u] = unique([index; A], 'rows');
Response = bsxfun(@eq, u(1:G), u(G+1:end).');
toc

给予

Elapsed time is 1.081043 seconds.

答案 2 :(得分:3)

您可以reshape矩阵,以便每一行都位于第三维。然后,我们可以使用隐式扩展(对于R2016b或更早版本,请参见bsxfun)来实现所有元素的相等性,并使用all在行上进行聚合(即,如果给定行的所有值都不相等,则为false)。

Response = all( reshape( index, [], 1, size(index,2) ) == reshape( A, 1, [], size(A,2) ), 3 ); 

您甚至可以通过在另一维度上使用all来避免某些重塑,但是我可以通过这种方式将其形象化。