Kristada673
Kristada673

Reputation: 3744

Is there a fast way to count occurrences of items in a matrix and save them in another matrix without using loops?

I have a time-series matrix X whose first column contains user ID and second column contains the item ID they used at different times:

X=[1 4
  2 1
  4 2
  2 3
  3 4
  1 1
  4 2
  5 3
  2 1
  4 2
  5 4];

I want to find out which user used which item how many times, and save it in a matrix Y. The rows of Y represent users in ascending order of ID, and the columns represent items in ascending order of ID:

Y=[1    0   0   1
   2    0   1   0
   0    0   0   1
   0    3   0   0
   0    0   1   1]

The code I use to find matrix Y uses 2 for loops which is unwieldy for my large data:

no_of_users = size(unique(X(:,1)),1);
no_of_items = size(unique(X(:,2)),1);
users=unique(X(:,1));
Y=zeros(no_of_users,no_of_items);

for a=1:size(A,1)
    for b=1:no_of_users
        if X(a,1)==users(b,1)
            Y(b,X(a,2)) = Y(b,X(a,2)) + 1;
        end
    end
end

Is there a more time efficient way to do it?

Upvotes: 0

Views: 93

Answers (1)

beaker
beaker

Reputation: 16821

sparse creates a sparse matrix from row/column indices, conveniently accumulating the number of occurrences if you give a scalar value of 1. Just convert to a full matrix.

Y = full(sparse(X(:,1), X(:,2), 1))

Y =

   1   0   0   1
   2   0   1   0
   0   0   0   1
   0   3   0   0
   0   0   1   1

But it's probably quicker to just use accumarray as suggested in the comments:

>> Y2 = accumarray(X, 1)

Y2 =

   1   0   0   1
   2   0   1   0
   0   0   0   1
   0   3   0   0
   0   0   1   1

(In Octave, sparse seems to take about 50% longer than accumarray.)

Upvotes: 7

Related Questions