For loop using unique values

21 vues (au cours des 30 derniers jours)
Jordan Cocanower
Jordan Cocanower le 24 Oct 2019
Commenté : Steven Lord le 24 Oct 2019
Have a 4 column matrix [DAY,MONTH,YEAR,DISCHARGE] and I am looking to incorporate a for loop to find the max value (DISCHARGE) associated with each unique value (MONTH). I don't really want to use the 'find' command over and over for each successive value of MONTH column, Thanks for helping
  2 commentaires
Daniel M
Daniel M le 24 Oct 2019
Modifié(e) : Daniel M le 24 Oct 2019
Have you tried using unique()? Also look at splitapply(), because it's likely you don't need a loop at all.
Jordan Cocanower
Jordan Cocanower le 24 Oct 2019
Thank you!

Connectez-vous pour commenter.

Réponse acceptée

Guillaume
Guillaume le 24 Oct 2019
Indeed using find would be madness. For the record, find is over used by beginners and is rarely needed. For that matters, for loop are also overused and are also not needed in this case.
There are many ways to do this:
maxdischarge = groupsummary(yourmatrix(:, 4), yourmatrix(:, 2), 'max');
Using splitapply:
[group, month] = findgroups(yourmatrix(:, 2)); %may not be needed if the month column is integers from 1 to 12
maxdischarge = splitapply(@max, yourmatrix(:, 4), group); %maxdischarge(i) corresponds to month(i)
Using old fashioned accumarray:
[month, ~, group] = unique(yourmatrix(:, 2)); %works like findgroups, with different order of output. Again may not be needed
maxdischarge = accumarray(yourmatrix(:, 4), group, [], @max);
Or even using a loop:
maxdischarge = zeros(12, 1)
for month = 1:12
maxdischarge = max(yourmatrix(yourmatrix(:, 2) == month, 4));
end
Note that I would recommend that you convert your matrix into a table:
t = array2table(yourmatrix, 'VariableNames', {'Day', 'Month', 'Year', 'Discharge'});
In which case, you definitively should use groupsummary:
groupsummary(t, 'Month', 'max', 'Discharge'); %calculate max of discharge grouped by month
Even better would be to convert the first 3 columns into a datetime array:
t = table(datetime(yourmatrix(:, 3), yourmatrix(:, 2), yourmatrix(:, 1)), yourmatrix(:, 4), 'VariableNames', {'Date', 'Discharge'});
groupsummary(t, 'Date', 'monthofyear', 'max', 'Discharge')
  2 commentaires
Jordan Cocanower
Jordan Cocanower le 24 Oct 2019
Incredibly helpful, thank you so much!
Steven Lord
Steven Lord le 24 Oct 2019
If you construct a datetime array you could store this data in a timetable and use retime to aggregate the data. See the "Aggregate Timetable Data and Calculate Mean Values" example on the retime documentation page. Instead of using 'hourly' and 'mean' you'd want to use 'monthly' and 'max'.

Connectez-vous pour commenter.

Plus de réponses (0)

Catégories

En savoir plus sur Data Preprocessing dans Help Center et File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by