unique values from from two column

I have a matrix
A=[1 2 3;
2 4 6;
5 3 2;
8 5 4;
6 7 8]
from this matrix, i want that value in first and second column will not get repeated. For eg. in 1st row 2 is in second column and in second row 2 is in 1st column. Please tell me how we can compare these two rows based on first two column and can get only that row whose value in the third column is greater.
Eg:
Output = [ 2 4 6;
8 5 4;
6 7 8]
Only two column (1, 2) will be compared to get the value from third column.

2 Comments

Are you guaranteed that there will be at most two rows with equal values, as in your example? Or could it be like this ...
A=[1 2 3;
2 4 6;
5 2 7]
or like this ...
A=[1 2 3;
2 4 6;
5 2 7;
2 5 4]
Could you have a pattern that connects different rows, like this ...
A=[1 2 3;
2 5 6;
5 1 7]
(note that the 2 and the 5 commingle different rows) or like this ...
A=[5 2 3;
2 5 6]
Could you have equal values in the third column?
A = [1 2 6;
2 5 6];
Which row(s) should be kept?
yes cyclist, u r interpreting it correctly, plzz try helping me with some logic.

Sign in to comment.

 Accepted Answer

The description of your problem is at best ambiguous.
This produces the result you posted:
Output = A(~any(A(:,[2 3]) == 2, 2),:)
produces:
Output =
2 4 6
8 5 4
6 7 8
It obviously tests on the presence of ‘2’ in the second and third columns, since ‘2’ appears to be important here. Note that in row 2 of your desired ‘Output’ matrix, column 3 is less than the other two elements. I see no pattern other than that expressed in my code.

8 Comments

I agree that the question has much ambiguity. (See my lengthy comment above.)
But I think what they mean is ...
First, find rows that have a common value in the first and second columns. For example, rows 1 & 2 get compared, because they share the value "2". Similarly, rows 3 & 4 get compared, because they share the value "5".
Next, for each set of rows that get compared, choose the row that has the largest value in column 3. For example, from the pair
1 2 3;
2 4 6;
choose [2 4 6]. And for the pair
5 3 2;
8 5 4;
choose [8 5 4].
The last row has no shared values with any other rows, so no comparisons need be made, and it just comes along for the ride.
At least, that's how I interpreted it. But I don't care to design an algorithm until all the other ambiguities are resolved.
yes it is correct for this example, thankyou. but it is not about 2. I want a code that can solve my probelm with original data.
what if the data is like
A=[1 2 4;
2 4 6;
5 3 9;
8 5 10;
6 7 8]
output =[2 4 6
8 5 10
6 7 8]
NOTE: please donot consider it about any number. just try to help me with some logic that can compare 1,2 column and if there is repeated value in any of the column then based on bigger value in column 3, output matrix will be formed.
Star Strider
Star Strider on 31 Aug 2019
Edited: Star Strider on 31 Aug 2019
@Cyclist — You could well be correct. I gave up on the problem description because it just doesn’t make sense. I then looked for the only pattern I saw that could give the result desired, and coded it.
I am not certain how robust this is (I did not test it on other (Nx3) matrices), however it works with this example, using the intended logic:
[C,ia,ib] = intersect(A(:,1),A(:,2),'stable'); % Column Value Intersections
[~,C1] = max(A(ia,3)); % Index Of Column 3 Maxima For Common Elements Indexed By ‘ia’
[~,C2] = max(A(ib,3)); % Index Of Column 3 Maxima For Column Elements Indexed By ‘ib’
C3 = setdiff((1:size(A,1)), [ia; ib]); % Other Rows
Output = A([ia(C1); ib(C2); C3(:)],:) % Desired Result
This is the most efficient code I can write for this.
Thankyou, this really helped me.
As always, my pleasure!
@star Strider. Thanks for your previous help. But i was trying to implement the same logic for the data given below for getting the desired result and it is creating some problem please help me with this output.It is 23*3 matrix as input and 14*3 matrix as output with no repeated column value of 2 and 3
A=[29.78 5 8
24.97 8 11
22.98 4 12
21.05 12 13
24.78 1 16
25.53 26 29
21.43 2 32
29.94 11 33
29.57 15 35
28.43 17 36
11.49 23 37
13.69 37 38
26.97 28 39
16.25 25 40
27.36 36 41
4.24 18 42
19.39 39 44
29.93 16 45
25.83 30 46
26.09 40 47
27.58 24 48
28.61 41 49
29.41 48 50]
and i want
output =[22.98 4 12
25.53 26 29
21.43 2 32
29.94 11 33
29.57 15 35
28.43 17 36
13.69 37 38
26.97 28 39
4.24 18 42
29.93 16 45
25.83 30 46
26.09 40 47
28.61 41 49
29.41 48 50 ]
Try this:
[C,ia,ib] = intersect(A(:,2),A(:,3),'stable'); % Columns (2,3) Value Intersections
for k = 1:numel(ia)
Ac = {A(ia(k),:), A(ib(k),:)}; % Cell Array Of ‘Matching’ Rows
[~,Ix1] = max([A(ia(k),1), A(ib(k),1)]); % Index Of Maximum Of ‘Ac’
Output(k,:) = Ac{Ix1}; % Preliminary Output Matrix
end
Ix2 = setdiff((1:size(A,1)), [ia; ib]); % Other Rows
Output = [Output; A(Ix2,:)] % Complete Output Matrix
producing:
Output =
29.78 5 8
22.98 4 12
29.94 11 33
13.69 37 38
28.43 17 36
26.97 28 39
29.93 16 45
26.09 40 47
28.61 41 49
29.41 48 50
25.53 26 29
21.43 2 32
29.57 15 35
4.24 18 42
25.83 30 46
My initial intent was to avoid the (explicit) loop, however it turned out to be the best option. (This is a more general version of my earlier code.) When I checked the result, it appears to be correct, although it found one more row (row 1 in my result) than in your example.

Sign in to comment.

More Answers (0)

Categories

Find more on Operators and Elementary Operations in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!