由Matlab匹配

时间:2013-07-26 13:58:39

标签: matlab

A =[1;2;3;4;5]
B= [10 1 ;11 2;19 5]

我想要

D = [1 10 ;2 11; 3 -9; 4 -9; 5 19]

也就是说,如果B(:,2)中不存在A中的某些内容,则D的第2列应为-9。

如果B(:,2)中存在A中的某个东西,我想把B的第1列的相应行放在D的第2列。

我知道如何使用ismember和for和if的组合来完成它。但我需要一种更优雅的方法,不使用“for”来加速它。

4 个答案:

答案 0 :(得分:4)

除非我遗漏某些内容(或A不是索引的向量),否则这实际上要简单得多,根本不需要ismemberfind索引:

D = [A zeros(length(A),1)-9];
D(B(:,2),2) = B(:,1)

为您的示例矩阵提供

D =

    1    10
    2    11
    3    -9
    4    -9
    5    19

答案 1 :(得分:2)

对于一般A

A =[1;2;3;4;6]; % Note change in A
B= [10 1 ;11 2;19 5];

[aux, where] = ismember(A,B(:,2));
b_where = find(where>0);
D = [(1:length(A)).' repmat(-9,length(A),1)];
D(b_where,2) = B(where(b_where),1);

这给出了

D = [ 1    10
      2    11
      3    -9
      4    -9
      5    -9 ]

答案 2 :(得分:1)

我不确定这个解决方案的效率如何,但它避免使用任何循环,所以至少它是一个开始的地方:

D = [A -9*ones(size(A))];           % initialize your result
[tf, idx] = ismember(A, B(:,2));    % get indices of matching elements
idx(idx==0) = [];                   % trim the zeros
D(find(tf),2) = B(idx,1);           % set the matching entries in D to the appropriate entries in B

disp(E)

您提前分配矩阵以节省时间(在MATLAB中动态构建矩阵非常慢)。 ismember调用返回真假向量tf,显示A的哪些元素对应B中的内容,以及它们对应的相关索引idxidx的问题在于,ft为零时,它包含零,这就是我们使用行idx(idx==0) = [];清除这些零的原因。最后,find(tf)用于获取与目标上的匹配关联的索引(在这种情况下为D的行),并且我们将这些索引处的值设置为等于{{1中的对应值我们想要的。

答案 3 :(得分:0)

首先创建一个临时矩阵:

tmp=[B; -9*ones(size(A(~ismember(A,B)))), A(~ismember(A,B))]
tmp =    
    10     1
    11     2
    19     5
    -9     3
    -9     4

然后使用find获取第一行索引,其中A的第二列中的tmp元素匹配(按设计总是匹配)。

D=[A, arrayfun(@(x) tmp(find(tmp(:,2)==x,1,'first'),1),A)];
D =    
     1    10
     2    11
     3    -9
     4    -9
     5    19

作为第二步的替代方案,您只需根据第二列对tmp进行排序:

[~,I]=sort(tmp(:,2));
D=[tmp(I,2), tmp(I,1)]
D =
    1    10
    2    11
    3    -9
    4    -9
    5    19