필터 지우기
필터 지우기

Find least frequent value in an array

조회 수: 4 (최근 30일)
Marcus Johnson
Marcus Johnson 2023년 9월 27일
답변: Steven Lord 2023년 9월 27일
Hello,
Let's say I have an array:
H = [1 1 2 2 3 3 4 5 5 5]
and if I use mode(H) I would get 5 since it's the most frequent, but can I do the opposite and find the least frequent? i.e. 4 in this case
  댓글 수: 1
Dyuman Joshi
Dyuman Joshi 2023년 9월 27일
What if there are two (or more) values which occur the least frequent?
For e.g.
H = [1 2 3 1 2 2 3 4 3 3 5 3 5 6]
Here, 4 and 6 occur only once. What should be the output in here and in such cases?

댓글을 달려면 로그인하십시오.

답변 (3개)

Steven Lord
Steven Lord 2023년 9월 27일
H = [1 1 2 2 3 3 4 5 5 5 6]
H = 1×11
1 1 2 2 3 3 4 5 5 5 6
[counts, values] = histcounts(H, [unique(H) Inf])
counts = 1×6
2 2 2 1 3 1
values = 1×7
1 2 3 4 5 6 Inf
allMinimumCountsLocations = counts == min(counts)
allMinimumCountsLocations = 1×6 logical array
0 0 0 1 0 1
values(allMinimumCountsLocations)
ans = 1×2
4 6
I added Inf at the end of the list of unique values so that the last bin contained only the last value from unique(H) rather than the last two. If I had omitted it, the last bin would have contained both 5 and 6 (both of the last two edges) rather than just 6. This is not a bug; see the description of the edges input argument or the BinEdges name-value argument on the histcounts documentation page.
[counts, values, bins] = histcounts(H, unique(H))
counts = 1×5
2 2 2 1 4
values = 1×6
1 2 3 4 5 6
bins = 1×11
1 1 2 2 3 3 4 5 5 5 5
valuesInLastBin = H(bins==max(bins))
valuesInLastBin = 1×4
5 5 5 6

Voss
Voss 2023년 9월 27일
편집: Voss 2023년 9월 27일
H = [1 1 2 2 3 3 4 5 5 5];
[uu,ii] = unique(sort(H(:)));
[~,idx] = min(diff([ii; numel(H)+1]));
result = uu(idx)
result = 4
% another example:
H = randi(5,10,10)
H = 10×10
1 5 4 1 3 3 3 5 2 3 2 1 5 1 2 3 2 1 2 4 2 3 5 5 4 5 2 5 3 2 1 1 1 2 4 5 5 2 1 1 1 3 2 5 2 3 2 5 4 3 2 3 3 5 2 4 2 4 3 2 5 2 4 1 1 2 5 5 4 1 1 4 4 1 1 3 1 4 2 3 2 3 5 2 4 3 4 4 3 2 4 1 4 3 1 2 1 1 4 5
for i = 1:5
fprintf('%d appears %d times\n',i,nnz(H == i))
end
1 appears 22 times 2 appears 24 times 3 appears 19 times 4 appears 18 times 5 appears 17 times
[uu,ii] = unique(sort(H(:)));
[~,idx] = min(diff([ii; numel(H)+1]));
result = uu(idx)
result = 5
  댓글 수: 1
Voss
Voss 2023년 9월 27일
Note that in case more than one element of H appears the least often, this method returns the lowest valued one, just like mode() does with the most frequently appearing value.
H = [2 2 3 3 4 5 5 5 0 1 1 1];
mode(H) % returns 1, not 5
ans = 1
[uu,ii] = unique(sort(H(:)));
[~,idx] = min(diff([ii; numel(H)+1]));
result = uu(idx) % returns 0, not 4
result = 0
But you can modify it:
[uu,ii] = unique(sort(H(:)));
d = diff([ii; numel(H)+1]);
result = uu(d == min(d)) % returns 0 and 4
result = 2×1
0 4
And you can use a similar approach to get multiple most-frequent elements in case there are more than one:
[uu,ii] = unique(sort(H(:)));
d = diff([ii; numel(H)+1]);
result = uu(d == max(d)) % returns 1 and 5
result = 2×1
1 5

댓글을 달려면 로그인하십시오.


Star Strider
Star Strider 2023년 9월 27일
편집: Star Strider 2023년 9월 27일
One approach —
H = [1 1 2 2 3 3 4 5 5 5];
[Hu,~,uidx] = unique(H, 'stable');
[Out,idx] = min(accumarray(uidx,(1:numel(uidx)).', [], @(x)numel(H(x))));
Result = Hu(idx)
Result = 4
EDIT — (27 Sep 2023 at 17:02)
Addressing Dyuman Joshi’s Comment, my code changes to —
H = [1 2 3 1 2 2 3 4 3 3 5 3 5 6];
[Hu,~,uidx] = unique(H, 'stable');
Out = accumarray(uidx,(1:numel(uidx)).', [], @(x)numel(H(x)));
Result = Hu(find(Out == min(Out)))
Result = 1×2
4 6
.

카테고리

Help CenterFile Exchange에서 File Operations에 대해 자세히 알아보기

제품


릴리스

R2023a

Community Treasure Hunt

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

Start Hunting!

Translated by