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

8 visualizzazioni (ultimi 30 giorni)
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 Commento
Jan
Jan il 30 Apr 2019
Modificato: Jan il 30 Apr 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.

Accedi per commentare.

Risposta accettata

Jan
Jan il 30 Apr 2019
Modificato: Jan il 30 Apr 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 Commento
Yaser Khojah
Yaser Khojah il 30 Apr 2019
Dear Jan Thanks a lot and this is really help. I have been trying hard to get an answer for this question.

Accedi per commentare.

Più risposte (0)

Categorie

Scopri di più su Parallel Computing Fundamentals in Help Center e File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by