patternMinor
Extract the largest value for each day from a matrix
Viewed 0 times
theeachvaluelargestforextractfrommatrixday
Problem
I have a matrix in which the right-most elements are repeated YYYYMMDD dates in descending order, for example:
Within each date, I want to keep only the row that corresponds to the largest element in the leftmost column. So I would like to produce a new matrix:
The code I have now is:
Are there ways to improve this code? I'm looking for coding conventions, improve performance, possible vectorization etc.
40 1122 1711 20160326
169 700 950 20160326
40 1630 1711 20160326
182 700 950 20160327
40 1029 1711 20160327
169 700 950 20160327
40 1630 1711 20160327
122 700 950 20160328
40 1630 1711 20160328
169 700 950 20160328
40 1630 1711 20160328
3049 700 950 20160331
40 1630 1711 20160331
3049 700 950 20160331
40 1630 1711 20160331
169 700 950 20160401
40 1630 1711 20160401
169 700 950 20160401
40 1630 1711 20160401Within each date, I want to keep only the row that corresponds to the largest element in the leftmost column. So I would like to produce a new matrix:
169 700 950 20160326
182 700 950 20160327
169 700 950 20160328
3049 700 950 20160331
169 700 950 20160401The code I have now is:
idx1 = find([1;diff(A(:,4))]);
idx2 = find([diff(A(:,4));1]);
B = zeros(length(idx1),4);
for ii = 1:length(idx1)
row_number = find(A(idx1(ii):idx2(ii),1) == max(A(idx1(ii):idx2(ii),1)),1);
B(ii,:) = A(idx1(ii)+row_number-1,:);
endAre there ways to improve this code? I'm looking for coding conventions, improve performance, possible vectorization etc.
Solution
A few notes: (I implemented this in Octave, so there may be differences between my code and a proper Matlab implementation, but there shouldn't be).
-
First we care about only unique dates, right? So lets grab
indices for their groupings. I'm assuming this original data is
stored in the matrix
Now
ignore the other returns by putting
-
Second, let's split out data up based on these groups. We can use
the function
pass in the function handle
within these groups.
There is some trick to get each row corresponding to that maximum value based on the
-
First we care about only unique dates, right? So lets grab
indices for their groupings. I'm assuming this original data is
stored in the matrix
A.[X, y, z] = unique(A(:, 4))Now
z is the only value I used from this output, so you couldignore the other returns by putting
~ in their place.-
Second, let's split out data up based on these groups. We can use
the function
accumarray() to accomplish this nicely. If wepass in the function handle
@max to it, it'll even find the maxwithin these groups.
B = accumarray(z, A(:, 1), [], @max)There is some trick to get each row corresponding to that maximum value based on the
z parameter, but after investigating this for a few hours I still haven't figured it out and have given up. You could try using find() to get these rows instead, using z to make sure we are grabbing the right values.Code Snippets
[X, y, z] = unique(A(:, 4))B = accumarray(z, A(:, 1), [], @max)Context
StackExchange Code Review Q#133465, answer score: 4
Revisions (0)
No revisions yet.