Find the max value and index of each interval in a big matrix
4 views (last 30 days)
Show older comments
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 Comment
Jan
on 30 Apr 2019
Edited: Jan
on 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.
Accepted Answer
Jan
on 30 Apr 2019
Edited: Jan
on 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
More Answers (0)
See Also
Categories
Find more on Matrices and Arrays in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!