我在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具有尺寸nx6,例如
B=[ 1 1 1 1 | 1 1;
1 2 3 1 | 1 1]
我想合并A和B并按照这些步骤创建矩阵C而不使用循环:
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')),:)];
最佳答案 使用
unique
和
accumarray
的组合非常容易.独特的工作方式是为您提供输出矩阵,其中删除所有重复条目.当玩A和B时,这将很好地工作.
只需将A和B连接成一个统一矩阵,然后对前4列使用unique,并为此截断矩阵的每一行分配一个唯一ID. unique的第三个输出将为您提供该ID,如果您想知道哪个ID对应于哪个行,那么该值来自unique的第一个输出,其中输出的每一行都为您提供它对应的ID.
您可以使用’rows’和’stable’标志来确保我们查看每一行而不是矩阵中的每个单独元素,并使用’stable’标志,我们根据当我们遇到来自开始(顶部)到结束(底部).如果你没有放入’stable’标志,它会在内部对行进行排序,然后从这个排序列表的顶部到底部分配ID.
如果要获得所需的输出,必须使用“稳定”.找到这些ID后,分别在第五列和第六列上使用accumarray两次,并应用单独的总和并将结果组合在一起. accumarray通过提供一组ID或密钥来工作,并且对于每个ID /密钥,存在与该密钥相关联的输出值.您将共享相同键的所有值分组,并对每个组执行某些操作.在我们的例子中,我们将在第一组输出值来自第五列的情况下应用accumarray两次,第二组输出值来自第六列. accumarray的默认行为是对属于同一组的所有值求和,这是您想要的.
在我们的例子中,accumarray的输出将是一个单列向量,它与第一步中使用唯一生成的唯一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