Reputation: 2299
I have two matrices in Matlab A
and B
respectively of dimension MxN
and GxN
.
M
can be greater or smaller than G
.
A
and B
do not contain identical rows.
I want to construct a matrix C
of dimension Hx(N+2)
in the following way
C=[];
for i=1:size(A,1)
%if A(i,1:end-1) coincides with a row in B(:,1:end-1) (it can coincide with only one row at most)
%then C=[C;A(i,1:end) B(j,end)]; %where j is the index of the identical row in B
%otherwise impose C=[C;A(i,1:end) 0]
end
for i=1:size(B,1)
%if B(i,1:end-1) does not coincide with any row in A(:,1:end-1)
%then impose C=[C; B(i,1:end-1) 0 B(i,end)];
end
For example:
A=[1 2 3 4 5 100; 6 7 8 9 10 101; 11 12 13 14 15 102];
B=[6 7 8 9 10 103; 15 16 17 18 19 104]
C=[1 2 3 4 5 100 0; 6 7 8 9 10 101 103; 11 12 13 14 16 102 0; 15 16 17 18 19 0 104]
As M
and G
can be very high, I am looking for the fastest way to perform this.
Upvotes: 1
Views: 79
Reputation: 15837
You can use ismember
+ indexing to do your task:
[idx1,idx2] = ismember(A(:,1:end-1), B(:,1:end-1), 'rows');
idx3 = ~ismember(B(:,1:end-1), A(:,1:end-1), 'rows');
C(idx1,:) = [A(idx1,:) B(idx2(idx1),end)];
C(~idx1,:) = [A(~idx1,:) zeros(sum(~idx1),1)];
C=[C;B(idx3,1:end-1) zeros(sum(idx3),1) B(idx3,end)];
Upvotes: 2
Reputation: 381
You could also use intersect
with a bit of preallocation to speed up the assignment (if M or G gets really large).
A=[1 2 3 4 5 100; 6 7 8 9 10 101; 11 12 13 14 15 102];
B=[6 7 8 9 10 103; 15 16 17 18 19 104];
C=[1 2 3 4 5 100 0; 6 7 8 9 10 101 103; 11 12 13 14 16 102 0; 15 16 17 18 19 0 104];
[M,N] = size(A);
G = size(B,1);
[tmp, idxA, idxB] = intersect(A(:,1:end-1),B(:,1:end-1),'rows')
idxBnotA = setdiff([1:G],idxB);
H = M + G - length(idxA);
C1 = zeros(H,N+1);
C1(1:M,1:N) = A;
C1(idxA,end) = B(idxB,end);
C1(M+1:end,1:end-2) = B(idxBnotA,1:end-1);
C1(M+1:end,end) = B(idxBnotA,end)
Upvotes: 1