Reputation: 207
I am trying to find unique values in one column of a matrix subject to the max amount listed in col 2 of the same matrix.
My code is the following:
Testing = find(unique(RAW_DATA_2(:,1))&max(RAW_DATA_2(:,2)))
To me it reads find unique items in col 1 of the matrix which are also the max of col 2. Matlab disagrees with me however.
An alternative is to not even use the find function and just return a matrix with just the unique values and the max amount for each unique value which would be preferable. I have attempted to use some code I found here on Stack overflow to do this but am having issues with it since I cannot modify it from "first" to "unique".
I = true(size(RAW_DATA_2,1),1);
idx = [];
while any(I)
idx(end+1) = find(I,1,'first'); %#ok
I = I & all(~bsxfun(@eq, RAW_DATA_2, RAW_DATA_2(idx(end),:)),2);
end
result = RAW_DATA_2(idx,:);
Upvotes: 2
Views: 102
Reputation: 221574
It seems an accumarray
based solution might also be a good fit here -
%// Find unique elements from column-1 and also tag/ID each of its elements
[col1_unq,~,id] = unique(RAW_DATA_2(:,1),'stable');
%// Get the max from second column based on the IDs and then concatenate
%// with unique rows from column-1 for the final output
result = [col1_unq accumarray(id,RAW_DATA_2(:,2),[],@max)]
Sample run -
RAW_DATA_2 =
12.5000 5.0000
12.5000 2.5000
5.0000 12.5000
10.0000 10.0000
7.5000 7.5000
7.5000 10.0000
12.5000 7.5000
5.0000 10.0000
result =
12.5000 7.5000
5.0000 12.5000
10.0000 10.0000
7.5000 10.0000
Upvotes: 1
Reputation: 56
I think your clarifying comment makes the question a lot more understandable. You should consider adding it to the question itself. Here's some code that may help you
a = [0 10; 1 100; 3 175; 4 80; 1 200; 2 400; 3 150; 0 10]; % your raw data
asorted = unique(a, 'rows'); %returns unique rows, sorted by value
Note that asorted
does not contain any duplicate rows and is sorted in the following way:
asorted =
0 10
1 100
1 200
2 150
2 300
2 400
3 150
3 175
4 80
It is now clear that the lowermost row containing each unique element of column 1 is what we need. This can be accomplished as follows:
diffidx = [diff(asorted(:, 1)); 1]; % appending 1 because the last row
% must always be included
result = asort(diffidx~=0, :)
Upvotes: 2
Reputation: 5821
This will work, but it might be a bit excessive if you have a lot of unique dates.
m = max( bsxfun(@times, A(:,2), bsxfun(@eq,unique(A(:,1))',A(:,1)) ));
answer = [unique(A(:,1)), m']
As an example with 4 dates, 1,2,3,4
:
2 65
2 16
3 94
4 25
3 63
4 26
3 50
4 82
1 92
3 16
1 49
1 100
2 62
1 44
3 34
My output is the following, with the "dates" on the left and their corresponding maxima on the right.
1 100
2 65
3 94
4 82
Upvotes: 1