Replace double numbers in a matrix with new ones

How can I ensure that 2 matrices have numbers from 1 to 40. BUT the columns of the two matrices are different, so that the numbers that appear in the first matrix may not appear in the second matrix in the first column.
Therefore, I can check whether a number that is in the 1st column of the 1st matrix is also in the 1st column of the 2nd matrix and if this is the case, then this number (from the 1st column of the 2nd matrix) should be assigned another number that is not in the 1st column of the 1st matrix.

Answers (1)

found = ismember(SecondMatrix(:,1), FirstMatrix(:,1));
now reassign Secondmatrix(found, 1)
... or, you know, you could do
temp = randperm(40);
FirstMatrix(:,1) = temp(1:20);
SecondMatrix(:,1) = temp(21:40);
Guaranteed that afterwards, no entry in SecondMatrix(:,1) appears in FirstMatrix(:,1)

11 Comments

The only problem is that I want both matrices to contain numbers from 1 to 40.
FirstMatrix=reshape(randperm(40),4,10); SecondMatrix=reshape(randperm(40),4,10);
I.e. I have a function that finds out whether a number in the 1st column of matrix 1 occurs in the 1st column of the 2nd matrix and if this is the case, this number is to be replaced by another number that lies between characters 1 and 40 but no duplications are to occur.
I therefore thought of: „setdiff“ but unfortunately this does not work in the end.
temp = randperm(40);
t1 = temp(1:20);
t2 = temp(21:40);
FirstMatrix(:,1) = t1;
FirstMatrix(:,2) = t2(randperm(20));
SecondMatrix(:,1) = t2;
SecondMatrix(:,2) = t1(randperm(20));
disp(FirstMatrix)
26 36 11 37 23 19 34 31 7 3 40 33 38 30 15 17 10 29 27 4 13 5 25 39 18 2 21 12 9 24 22 28 1 16 6 14 8 20 35 32
disp(SecondMatrix)
29 8 19 1 16 35 30 25 4 26 20 34 24 23 28 7 33 22 17 11 31 10 3 13 12 18 39 27 37 21 2 38 32 40 36 9 5 15 14 6
find(ismember(SecondMatrix(:,1), FirstMatrix(:,1)))
ans = 0×1 empty double column vector
My mistake, I did not express myself correctly.
It is true that this above procedure causes the numbers in the columns to vary, however. My matrices are constructed as follows:
FirstMatrix=reshape(randperm(40),4,10); SecondMatrix=reshape(randperm(40),4,10);
Therefore, I do not want the column contents to appear again in the same form in the other matrix. I do not want the number assignments from the first matrix to reappear in the second.
So the numbers of the 1st column of the 1st matrix should not appear 1:1 (regardless of the order) in the 2nd matrix.
Therefore, I would like to mix the numbers and only then divide them, but my only condition is that if the number was already in the 5th column in the previous matrix, then it should not appear again in the 5th column in the current matrix.
E.g. Starting from my matrices above
I get something like this:
In this case I don't want the numbers 15,26,4 and 17 from the 3rd column to appear in the 2nd matrix in the 3rd column and basically no other column is filled with these numbers (because then the column would be filled with the same numbers as in one and I don't want that, even if the order varies).
In this example, none of the 3rd column of the 1st matrix is in the 3rd column of the 2nd matrix, so it fits.
Only what does not fit is the number 31 in the 2nd column of the 2nd matrix and the number 12 in the 5th column of the 2nd matrix. Because these already appear in the columns of the previous matrix.
I hope it is now easier to understand. Many thanks already :)
FirstMatrix=reshape(randperm(40),4,10)
FirstMatrix = 4×10
9 18 15 3 39 24 19 35 13 5 7 14 26 27 23 8 20 25 28 16 21 31 4 6 12 37 36 10 1 11 38 33 17 29 2 30 32 34 22 40
SecondMatrix=reshape(randperm(40),4,10)
SecondMatrix = 4×10
20 38 23 9 6 15 35 32 24 2 1 16 22 21 12 19 3 26 37 28 40 31 36 25 5 13 27 4 33 34 7 17 10 30 29 39 18 11 14 8
T1 = 1 : 40;
T2 = randperm(numel(T1),4)
T2 = 1×4
8 17 32 14
T1(T2) = [];
T3 = reshape(T1(randperm(numel(T1))), 4, [])
T3 = 4×9
33 28 15 38 1 2 22 34 40 5 4 30 6 16 21 24 25 31 11 29 39 18 26 13 7 19 10 3 23 36 12 35 20 9 37 27
That is, you can construct your arrays to not have any repetitions.
I don't quite understand, because I would end up with a matrix that is 4x9 and not 4x10.
I don't know exactly how to filter for the number that appears in the same columns of the two matrices (1 and 2). So that I can swap/replace it with a number that fits.
T1 = 1 : 40;
T2 = randperm(numel(T1),4)
T2 = 1×4
36 33 37 9
T1(T2) = [];
T3 = reshape(T1(randperm(numel(T1))), 4, [])
T3 = 4×9
20 17 16 7 31 28 18 11 26 1 15 13 4 3 35 39 34 8 30 19 5 40 2 21 29 12 24 38 27 22 14 25 10 32 6 23
output = [T2(:), T3]
output = 4×10
36 20 17 16 7 31 28 18 11 26 33 1 15 13 4 3 35 39 34 8 37 30 19 5 40 2 21 29 12 24 9 38 27 22 14 25 10 32 6 23
I don't know exactly how to filter for the number that appears in the same columns of the two matrices
My very first response was to show you how to use ismember() to do the filtering.
What I have been pointing out since then is that you can avoid that by strategic use of randperm and indexing. Pay attention to the way T3 was constructed: T1(T2) = []; on the line above removes from T1 all of the elements that were already used, and T1(randperm(numel(T1))) is then a random re-ordering of everything that is left over.
Yes, I understand. Do you know how to generate an if loop that tells me that if a number is duplicated in a column, the second number that is duplicated is replaced by a number that is not yet in the column?
I'm thinking about it all the time, but I can't figure out how to program it.
found = ismember(SecondMatrix(:,1), FirstMatrix(:,1));
if any(found)
SecondMatrix(found,1) = ReplacementValuesThatYouWouldCompute;
end
Loop not required. The ismember() will return a vector of values, one for each row in SecondMatrix. A value of true at a particular offset tells you that SecondMatrix(ThatOffset,1) is a duplicate of something inside FirstMatrix(:,1) . A value of false at a particular offset tells you that SecondMatrix row does not duplicate anything in the first column of FirstMatrix. It is not necessary to loop testing each row of SecondMatrix in turn.
Ok, thank you very much, that brings me a lot further.
However, I still have a question: I now proceed in such a way that the value that was already in the previous column is set as zero in the next one.
found = ismember(SecondMatrix(:,1), FirstMatrix(:,1));
if any(found)
SecondMatrix(found,1) = 0;
end
I now want to replace the zeros with the values that are not yet in the matrix (because I want all numbers up to 40 to be in it). Therefore I thought of finding out the missing values for the 2nd matrix. Is there perhaps a function with which I can recognise which values are still missing in the matrix and then put them in the appropriate column?
What is the use case? WHY do you want this thing? Is it homework, or is there some real world need for it?
found = ismember(SecondMatrix(:,1), FirstMatrix(:,1));
SecondMatrix(found,1) = 0;
candidates = setdiff(1:40, SecondMatrix(:,1));
SecondMatrix(found,1) = candidates(randperm(numel(candidates), sum(found)));

Sign in to comment.

Asked:

on 6 Aug 2023

Commented:

on 7 Aug 2023

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!