Search code examples
matlaboctaveaccumarray

Counting the same rows of 2D matrix


I have a two column matrix. I need to make it three column, where the third column shows the number of appearance of the first two as a row in the input matrix.

Basically: Input

[1 1;
 1 1;
 1 2;
 1 2;
 1 3]

Desired output:

[1 1 2;
 1 2 2;
 1 3 1]

I know already that a proper combination of accumarray and unique should do the charm. I just don't know how to properly combine them.


Solution

  • You are right, unique and accumarray are perfectly suited for this task:

    x = [1 1; 1 1; 1 2; 1 2; 1 3]; % input
    [~, v, w] = unique(x, 'rows', 'stable'); % unique indices and labels
    c = accumarray(w, 1); % counts
    y = [x(v,:) c]; % output
    

    Remove the 'stable' flag if you want the ouput rows sorted in lexicographical order.

    You can also replace accumarray by bsxfun to obtain the counts:

    c = sum(bsxfun(@eq, unique(w), w.'), 2);
    

    For the special case that the entries of x are positive integers and you want the ouput in lexicographical order, you can also use sparse and find as follows:

    x = [1 1; 1 1; 1 2; 1 2; 1 3]; % input
    [ii,jj,vv] = find(sparse(x(:,1), x(:,2), 1));
    y = [ii(:), jj(:), vv(:)]; % output