필터 지우기
필터 지우기

Maximum number of repeated values over an array

조회 수: 8 (최근 30일)
Alessandro Togni
Alessandro Togni 2021년 1월 20일
댓글: Stephen23 2021년 1월 20일
Hi,
i'm working with an array of thousands of elements and i've to limit the repeated values to 10.
Let say:
a=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9];
has to become:
[0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,9].
Any suggestion would be appreciated.
Thanks in advance,
Alessandro

채택된 답변

Stephen23
Stephen23 2021년 1월 20일
편집: Stephen23 2021년 1월 20일
a = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9];
x = cumsum([true;diff(a(:))~=0]);
f = @(v){v(1:min(end,10))};
c = accumarray(x,a(:),[],f);
b = vertcat(c{:}).'
b = 1×28
0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 5 0 0 0 0 0 0 0 0 0 0 9
  댓글 수: 2
Alessandro Togni
Alessandro Togni 2021년 1월 20일
Thank you very much.
What if one would want to store the indexes of removed values?
Stephen23
Stephen23 2021년 1월 20일
a = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9];
d = find([true;diff(a(:));true]);
f = @(b,e)(b+10):(e-1);
c = arrayfun(f,d(1:end-1),d(2:end),'uni',0);
x = horzcat(c{:})
x = 1×21
11 12 13 14 15 16 17 18 19 20 21 22 40 41 42 43 44 45 46 47 48

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

추가 답변 (1개)

Jan
Jan 2021년 1월 20일
편집: Jan 2021년 1월 20일
a = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0, ...
5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9];
[v, n] = RunLength(a);
b = RunLength(v, min(n, 10));
If you do not have a C compiler installed, use the function RunLength_M of this submission.
Alternatively:
function out = LimitRunLength(in, nMax)
x = in(:);
d = [true; diff(x) ~= 0]; % TRUE if values change
b = x(d); % Elements without repetitions
k = find([d', true]); % Indices of changes
n = diff(k); % Number of repetitions
n = min(n, nMax); % Limit the run lengths
d = cumsum(n); % Cummulated run lengths
index = zeros(1, d(end)); % Pre-allocate
index(d(1:end-1)+1) = 1; % Get the indices where the value changes
index(1) = 1; % First element is treated as "changed" also
out = b(cumsum(index)); % Cummulated indices
% Let the output be a row vector, if the input is a row:
if size(in, 2) > 1
out = out.';
end
end
[EDITED] You ask for the indices of the removed elements:
a = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,5, ...
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9];
nMax = 10;
[v, n, idx] = RunLength_M(a);
b = RunLength_M(v, min(n, nMax));
crop = find(n > nMax);
idx = [idx, numel(a) + 1];
q = zeros(1, numel(a));
q(idx(crop) + nMax) = 1;
q(idx(crop + 1)) = -1;
removed = find(cumsum(q));
And as next alternative a straight forward loop:
del = false(size(a));
cur = NaN;
for k = 1:numel(a)
if a(k) == cur
len = len + 1;
del(k) = (len > nMax);
else
cur = a(k);
len = 1;
end
end
b = a(~del);
removed = find(del);

카테고리

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

태그

제품

Community Treasure Hunt

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

Start Hunting!

Translated by