如何将一行的元素与同一矩阵中的每一行进行比较

时间:2009-11-17 16:04:23

标签: matlab matrix comparison

我有矩阵:

a = [ 1 2 3 4;
      2 4 5 6;
      4 6 8 9]

我希望将每一行与其他两行逐一进行比较。如果他们共享相同的密钥,那么结果将告诉他们有一个共同的密钥。

2 个答案:

答案 0 :(得分:4)

使用@gnovice关于使用 nchoosek 的所有组合的想法,我建议另外两个解决方案:

  • 使用 ismember (如@loren所述)
  • 另一个使用 bsxfun eq 函数句柄

唯一的区别是交叉排序并仅保留唯一的公共密钥。

a = randi(30, [100 20]);
%# a = sort(a,2);

comparisons = nchoosek(1:size(a,1),2);
N = size(comparisons,1);
keys1 = cell(N,1);
keys2 = cell(N,1);
keys3 = cell(N,1);

tic
for i=1:N
    keys1{i} = intersect(a(comparisons(i,1),:),a(comparisons(i,2),:));
end
toc

tic
for i=1:N
    query = a(comparisons(i,1),:);
    set = a(comparisons(i,2),:);
    keys2{i} = query( ismember(query, set) );             %# unique(...)
end
toc


tic
for i=1:N
    query = a(comparisons(i,1),:);
    set = a(comparisons(i,2),:)';
    keys3{i} = query( any(bsxfun(@eq, query, set),1) );   %'# unique(...)
end
toc

...进行以下时间比较:

Elapsed time is 0.713333 seconds.
Elapsed time is 0.289812 seconds.
Elapsed time is 0.135602 seconds.

请注意,即使事先对a进行排序并在循环(注释部分)中添加对unique的调用,这两种方法仍然比intersect更快。

答案 1 :(得分:3)

这是一个解决方案(可以推广到比问题中的样本更大的矩阵):

comparisons = nchoosek(1:size(a,1),2);
N = size(comparisons,1);
keys = cell(N,1);
for i = 1:N
  keys{i} = intersect(a(comparisons(i,1),:),a(comparisons(i,2),:));
end

函数NCHOOSEK用于生成行比较的所有唯一组合。对于问题中的矩阵a,您将获得comparisons = [1 2; 1 3; 2 3],这意味着我们需要比较第1行和第2行,然后是1和3,最后是2和3. keys是一个cell array,用于存储每个比较的结果。对于每次比较,函数INTERSECT用于查找公共值(即键)。对于问题中给出的矩阵a,您将获得keys = {[2 4], 4, [4 6]}