Maximum number of repeated values over an array

6 Ansichten (letzte 30 Tage)
Alessandro Togni
Alessandro Togni am 20 Jan. 2021
Kommentiert: Stephen23 am 20 Jan. 2021
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

Akzeptierte Antwort

Stephen23
Stephen23 am 20 Jan. 2021
Bearbeitet: Stephen23 am 20 Jan. 2021
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 Kommentare
Alessandro Togni
Alessandro Togni am 20 Jan. 2021
Thank you very much.
What if one would want to store the indexes of removed values?
Stephen23
Stephen23 am 20 Jan. 2021
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

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (1)

Jan
Jan am 20 Jan. 2021
Bearbeitet: Jan am 20 Jan. 2021
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);

Kategorien

Mehr zu Programming finden Sie in Help Center und File Exchange

Tags

Produkte

Community Treasure Hunt

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

Start Hunting!

Translated by