Star
Star

Reputation: 2299

Fastest code to merge two matrices of different dimension in Matlab

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

Answers (2)

rahnema1
rahnema1

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

Morc
Morc

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

Related Questions