1
v = [1,2,1,1,1,2,2]

1 and 2 are my two groups. I'm trying to increment each group by 1 every time there is a repetition

The desired result:

v2 = 
    1  1  2  3  4  2  3

I tried the functions cumsum and movsum with splitapply, but nothing has worked so far

HappyPy
  • 9,839
  • 13
  • 46
  • 68
  • Does this answer your question? [Count repeating integers in an array](https://stackoverflow.com/questions/54079558/count-repeating-integers-in-an-array) – obchardon May 23 '23 at 15:28
  • @obchardon I knew I had seen this (or something very similar) somewhere! However, in your question all equal values are adjacent, which simplifies the problem a little and allows for more approaches. [This](https://codegolf.stackexchange.com/q/178500/36398) PPCG challenge, linked in your question, may be a more exact "duplicate", but of course it won't contain the most practical approaches... – Luis Mendo May 23 '23 at 15:39

3 Answers3

2

I am using different values of v for more clarity:

v = [10, 20, 10, 10, 10, 20, 20];
  • Memory-efficient solution, with a loop over the unique values of v:

    [a, ~, c] = unique(v);
    v2 = zeros(size(v));
    for k = 1:numel(a)
        ind = c==k;
        v2(ind) = 1:sum(ind); 
    end
    
  • Memory-inefficient (it builds an intermediate N×N matrix, N = numel(v)), but simpler:

    v2 = sum(triu(v==v.'));
    
  • Another approach, probably memory-efficient too:

    s = sparse(c, 1:numel(c), 1);
    v2 = nonzeros(s.*cumsum(s, 2)).';
    
Luis Mendo
  • 110,752
  • 13
  • 76
  • 147
2

If you have few groups, you could iterate over the groups. As the number of groups increases this might become expensive though.

v = [1,2,1,1,1,2,2];

v2 = zeros(size(v));
for p = unique(v)
  i = v == p;
  v2(i) = 1:sum(i);
end
Cris Luengo
  • 55,762
  • 10
  • 62
  • 120
1

You say you only have 2 groups, so you can just add the cumulative sums of the Boolean when equal to one or the other

idx = (v==1);
v2 = cumsum(idx).*idx + cumsum(~idx).*(~idx);

For your example,

v = [1,2,1,1,1,2,2];
v2 = [1,1,2,3,4,2,3]

In the more generic case where you have more than two values, you can generalise this using implicit expansion at the cost of memory

idx = v == (unique(v).');
v2 = sum( cumsum(idx,2) .* idx );
Wolfie
  • 27,562
  • 7
  • 28
  • 55