MATLAB Answers

Compare two arrays (intersection) and create new array with output columns, but with repetitions

6 views (last 30 days)
Daniel Rohrer
Daniel Rohrer on 17 Nov 2019
Edited: per isakson on 18 Nov 2019
Hi,
I have following example arrays, and I want to write the values of the second array to a new array if the values of the first column intersect.
A = [1 3500; 2 100; 2 564; 3 2140; 3 9820; 2 8952]
B = [1 0 0 0.5; 2 0 0 0.8; 3 0 1 0; 4 0 1 0.5; 5 1 1 0; 6 1 1 0.5]
The output should look like this:
C = [0 0 0.5; 0 0 0.8; 0 0 0.8; 0 1 0; 0 1 0; 0 0 0.8]
I tried to use intersect, but it only returns with no repetition, ismember only returns logical and the position is irrelevant for me. And my workaround code does not rly give me what i like to have:
[~, rowsA, rowsB] = intersect(A(:, 1), B(:, 1));
C = [B(rowsB 2) B(rowsB, 3) B(rowsB, 4)];
% Code with ismember (workaround try)
v = intersect(B(:,1),A(:,1));
bmin = ismember(B(:,1),v(:,1));
bmax = ismember(A:,1),v(:,1));
imin = find(bmin);
imax = find(bmax);
S = B(imin);
T = A(imax);
Is there any workaround that I can use to create this output array?

  0 Comments

Sign in to comment.

Accepted Answer

per isakson
per isakson on 18 Nov 2019
Edited: per isakson on 18 Nov 2019
Your way of defining A, B and C makes me wonder whether you intended to define matrices, not vectors.
Anyhow, this is a different solution
%%
A = [1 3500, 2 100, 2 564, 3 2140, 3 9820, 2 8952];
B = [1 0 0 0.5, 2 0 0 0.8, 3 0 1 0, 4 0 1 0.5, 5 1 1 0, 6 1 1 0.5];
%% turn the vectors into the matrices I believe you intended to define
A = permute( reshape( A, 2,[] ), [2,1] );
B = permute( reshape( B, 4,[] ), [2,1] );
%%
[~,rowsB] = ismember( A(:,1), B(:,1) );
C = B( rowsB, 2:end );
%% and turn back into a row vector
reshape( permute( C, [2,1] ), 1,[] )
outputs
ans =
0 0 0.5 0 0 0.8 0 0 0.8 0 1 0 0 1 0 0 0 0.8 (edited)

  2 Comments

Daniel Rohrer
Daniel Rohrer on 18 Nov 2019
Hi,
Yes it is a matrice, so the permute part is not necessary. I've corrected it in my question, it was a bit late yesterday^^. It works exactly as I requested, unfortunately I get following error message:
C = B( rowsB, 2:end ); % error is from this line
Index in position 1 is invalid.
Array indices must be positive
integers or logical values.
I thought it's the zero value in the first row, as my real matrice starts like this:
A = [0 3300; 46 3796] % and so on
I removed my first rows to see if it now works, but I still get this error. Is there maybe any other cause which leads to this error? Both of my matrices have only integer values in the first column
Edit: I've found my mistake, C was already defined by the trial I've did with your proposal solution. It works perfectly fine now.
Thank you very much!
Best regards,
Daniel
per isakson
per isakson on 18 Nov 2019
My code assumes a happy path scenario. It assuses that all A(:,1) are members of B(:,1). I missed the if in "to a new array if the values of the first column intersect"
I replaced A by
A = [17 3500, 2 100, 2 564, 3 2140, 3 9820, 2 8952];
and got the same error as you did. 17 is not a member of B(:,1)-
>> Untitled
Index in position 1 is invalid. Array indices must be positive integers or
logical values.
Error in Untitled (line 9)
C = B( rowsB, 2:end );
In this case rowsB(1) is zero.
Proposal: Add the line
rowsB(rowsB==0) = [];
after
[~,rowsB] = ismember( A(:,1), B(:,1) );

Sign in to comment.

More Answers (1)

the cyclist
the cyclist on 17 Nov 2019
It's a little convoluted, but this should work:
A = [1 3500, 2 100, 2 564, 3 2140, 3 9820, 2 8952]
B = [1 0 0 0.5, 2 0 0 0.8, 3 0 1 0, 4 0 1 0.5, 5 1 1 0, 6 1 1 0.5]
[tf,index1] = ismember(A,B(1:4:end));
index2 = 4*index1(tf) - [2 1 0]';
C = B(index2(:))

  0 Comments

Sign in to comment.

Sign in to answer this question.

Products


Release

R2018b