在Matlab中合并两个不同维数的矩阵?

在Matlab中合并两个不同维数的矩阵?,matlab,Matlab,我在Matlab中有两个矩阵A和B。A具有尺寸mx6,例如 A=[ 1 1 1 1 | 1 0; 1 1 1 2 | 1 0; 1 1 1 3 | 1 0; 1 1 1 4 | 1 0; 1 2 3 2 | 1 0; 1 2 3 3

我在Matlab中有两个矩阵
A
B
。A具有尺寸
mx6
,例如

A=[  1     1     1     1   |  1     0;
     1     1     1     2   |  1     0;
     1     1     1     3   |  1     0;
     1     1     1     4   |  1     0;
     1     2     3     2   |  1     0;
     1     2     3     3   |  1     0;
     1     2     3     4   |  1     0]
B=[  1     1     1     1   |  1     1;
     1     2     3     1   |  1     1]
B
具有维度
nx6
,例如

A=[  1     1     1     1   |  1     0;
     1     1     1     2   |  1     0;
     1     1     1     3   |  1     0;
     1     1     1     4   |  1     0;
     1     2     3     2   |  1     0;
     1     2     3     3   |  1     0;
     1     2     3     4   |  1     0]
B=[  1     1     1     1   |  1     1;
     1     2     3     1   |  1     1]
我想合并
A
B
并按照以下步骤创建矩阵
C
,而不使用循环:

%STEP 1
     for i=1:size(B,1)
            for j=1:size(A,1)
                if all(B(i,1:4)==A(j,1:4),2)
                   C(i,:)=[B(i,1:4) A(j,5)+B(i,5) A(j,6)+B(i,6)]
                end
            end
        end



 %STEP 2


  C=[ C; A(logical(1-ismember(A(:,1:4), B(:,1:4),'rows')),:)];
  C=[ C; B(logical(1-ismember(B(:,1:4), A(:,1:4),'rows')),:)]; 
< P > 1)考虑<代码> B(I,1:4)< /代码>;如果存在
j
,使得
A(j,1:4)
等于
B(i,1:4)
[这最多可以发生在一个
j
]那么
C(i,:)=[B(i,1:4)A(j,5)+B(i,5)A(j,6)+B(i,6)]
。对所有
i=1,…,n
执行此操作

2) 用根据步骤1无法匹配的
A
B
行填充
C
的其余行

在这个例子中

C=[  1     1     1     1   |  2     1;  %Step 1) above
   ------------------------------------
     1     1     1     2   |  1     0;  %Step 2) above
     1     1     1     3   |  1     0;  %firstly rows from A
     1     1     1     4   |  1     0;
     1     2     3     2   |  1     0;
     1     2     3     3   |  1     0;
     1     2     3     4   |  1     0; 
     1     2     3     1   |  1     1]  %lastly rows from B
我尝试使用循环:

%STEP 1
     for i=1:size(B,1)
            for j=1:size(A,1)
                if all(B(i,1:4)==A(j,1:4),2)
                   C(i,:)=[B(i,1:4) A(j,5)+B(i,5) A(j,6)+B(i,6)]
                end
            end
        end



 %STEP 2


  C=[ C; A(logical(1-ismember(A(:,1:4), B(:,1:4),'rows')),:)];
  C=[ C; B(logical(1-ismember(B(:,1:4), A(:,1:4),'rows')),:)]; 

下面是一个不使用循环的解决方案。然而,我不太确定这会比循环快

ind = 1:size(B,1);

[indA, indA_true] = ismember(A(:,1:4),B(:,1:4),'rows');

indB = indA_true(find(indA_true));

C = [A(indA,1:4), A(indA,5:6) + B((indB),5:6)];

C = [C; A(~indA,:); B(~ismember(ind',indB,'rows'),:)];

使用和的组合非常容易
unique
通过向您提供一个输出矩阵来消除所有重复条目。在玩
A
B
时,这将非常有效

只需将
A
B
连接到一个合并矩阵中,然后对前4列使用
unique
,并为该截断矩阵的每一行分配一个唯一ID。
unique
的第三个输出将为您提供该ID,如果您想知道哪个ID对应于哪一行,它来自
unique
的第一个输出,其中输出的每一行都为您提供它对应的ID

您可以使用
'rows'
'stable'
标志来确保我们查看矩阵中的每一行而不是每一个单独的元素,使用
'stable'
标志,我们根据从开始(顶部)到结束(底部)遇到唯一行的时间来分配ID。如果您没有放置
'stable'
标志,它将在内部对行进行排序,然后从该排序列表的顶部到底部分配ID

如果要实现所需的输出,必须使用
“稳定”
。找到这些ID后,分别在第五列和第六列上使用
accumarray
两次,然后应用单独的总和并将结果合并在一起
accumarray
通过提供一组ID或键来工作,对于每个ID/键,都有一个与此键相关的输出值。您将共享同一个键的所有值分组,并对每个组执行一些操作。在本例中,我们将应用两次
accumarray
,其中第一组输出值来自第五列,第二组输出值来自第六列。
accumarray
的默认行为是对属于同一组的所有值求和,这是您想要的

在我们的例子中,
accumarray
的输出将是一个单列向量,其长度等于第一步使用
unique
生成的唯一ID总数。分别对第五列和第六列执行此操作,然后要获得最终矩阵,只需将
unique
的第一个输出以及两个
accumarray
输出合并到一个矩阵中,即可最终获得输出

大概是这样的:

%// Your data
A=[  1     1     1     1     1     0;
1     1     1     2     1     0;
1     1     1     3     1     0;
1     1     1     4     1     0;
1     2     3     2     1     0;
1     2     3     3     1     0;
1     2     3     4     1     0];
B=[  1     1     1     1     1     1;
1     2     3     1     1     1];

%// Solution
[cols,~,id] = unique([A(:,1:4); B(:,1:4)], 'rows', 'stable');
out = accumarray(id, [A(:,5); B(:,5)]);
out2 = accumarray(id, [A(:,6); B(:,6)]);
final = [cols out out2];
这是我们的产出:

final =

     1     1     1     1     2     1
     1     1     1     2     1     0
     1     1     1     3     1     0
     1     1     1     4     1     0
     1     2     3     2     1     0
     1     2     3     3     1     0
     1     2     3     4     1     0
     1     2     3     1     1     1

您是否编写了代码来尝试这样做?你有什么问题?我没有指定我不想使用循环。我不知道如何不使用循环来回答这个问题。刚刚编辑!请把你写的代码贴出来。