Find the max value and index of each interval in a big matrix

8 vues (au cours des 30 derniers jours)
Yaser Khojah
Yaser Khojah le 30 Avr 2019
Commenté : Yaser Khojah le 30 Avr 2019
I'm looking for a way to split my data into group then find the maximum and index of each group. So, I have this code which gives me the maximums but the indexes are not correct. Any idea please. I have asked this question and haven’t got the right answer yet. This is a simple example but in my big matrix there might be more than an answer. For example two max values. Is the code will select one only or will not work?
XX = [1 2 3 4 5 1 3]';
YY = [10 10 10 20 20 30 20]';
[uv,~,idx] = unique(XX);
[Result] = splitapply(@max, YY, idx);
figure
scatter(uv,Result)
line(uv,Result)
indices = splitapply(@maxIndex, YY, idx);
function out=maxIndex(z)
[~,out]=max(z);
end
m = [uv, Result, indices]
1 30 2
2 10 1
3 20 2
4 20 1
5 20 1
%The correct one should be
m =
1 30 6
2 10 2
3 20 8
4 20 4
5 20 5
If you like to test on my data, I have attached my data and code as below.
x = round(MaT_All(:,18),0);
y = MaT_All(:,17);
[uv,~,idx] = unique(x);
[Result] = splitapply(@max, y, idx);
figure
scatter(uv,Result)
line(uv,Result)
indices = splitapply(@maxIndex, y, idx);
function out=maxIndex(z)
[~,out]=max(z);
end
  1 commentaire
Jan
Jan le 30 Avr 2019
Modifié(e) : Jan le 30 Avr 2019
splitapply creates a group at first and applies the function afterwards. Then the maximum index ins related to the group, and not the absolute index in te input array.
I "the correct one should be" you get this row:
3 20 8
But the input has 7 elements only.
By the way, you can catch both outputs of max with 1 call of splitapply:
[Result, Indices] = splitapply(@max, y, idx);
so the function maxIndex is not needed. But this does not solve your question also.

Connectez-vous pour commenter.

Réponse acceptée

Jan
Jan le 30 Avr 2019
Modifié(e) : Jan le 30 Avr 2019
To be sure: Would this loop solve your problem?
XX = [1 2 3 4 5 1 3]';
YY = [10 10 10 20 20 30 20]';
uXX = unique(XX);
Result = zeros(size(uXX));
Index = zeros(size(uXX));
for k = 1:numel(uXX)
match = find(XX == uXX(k));
[Result(k), idx] = max(YY(match));
Index(k) = match(idx);
end
If so, try if this is faster:
XX = [1 2 3 4 5 1 3]';
YY = [10 10 10 20 20 30 20]';
[uv, ~, idx] = unique(XX);
[Result, Index] = splitapply(@maxIndex, [YY, (1:numel(YY)).'], idx)
function [value, index] = maxIndex(z)
[value, k] = max(z(:, 1));
index = z(k, 2);
end
Here the index related to the YY vector is appended as 2nd column, such that the related information is available inside maxIndex also.
Use timeit or tic/toc to compare the runtime with providing 2 separate arrays:
[uv, ~, idx] = unique(XX);
[Result, Index] = splitapply(@maxIndex, YY, (1:numel(YY)).', idx)
function [value, index] = maxIndex(Y, IndexY)
[value, k] = max(Y);
index = IndexY(k);
end
  1 commentaire
Yaser Khojah
Yaser Khojah le 30 Avr 2019
Dear Jan Thanks a lot and this is really help. I have been trying hard to get an answer for this question.

Connectez-vous pour commenter.

Plus de réponses (0)

Catégories

En savoir plus sur Parallel Computing Fundamentals 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