Reputation: 743
I would like to apply the function unique to each row of a given matrix, without involving any for loop. Suppose I have the following 4-by-5 matrix
full(A) = [0 1 0 0 1
2 1 0 3 0
1 2 0 0 2
0 3 1 0 0]
where A
is the corresponding sparse matrix. As an example using a for loop, I can do
uniq = cell(4,1);
for i = 1:4
uniq{i} = unique(A(i,:));
end
and I would obtain the cell structure uniq given by
uniq{1} = {1}
uniq{2} = {[1 2 3]}
uniq{3} = {[1 2]}
uniq{4} = {[1 3]}
Is there a quicker way to vectorize this and avoid for loops? I need to apply this to matrices M-by-5 with M large. Note that I'm not interested in the number of unique elements per row (I know there are around answers for such a problem).
Upvotes: 4
Views: 1129
Reputation: 4195
you can use num2cell(A,2)
to convert each row into cell and then cellfun
with unique
to get cell array of unique values from each row:
% generate large nX5 matrix
n = 5000;
A = randi(5,n,5);
% convert each row into cell
C = num2cell(A,2);
% take unique values from each cell
U = cellfun(@unique,C,'UniformOutput',0);
Upvotes: 2
Reputation: 112659
You can use accumarray
with a custom function:
A = sparse([0 1 0 0 1; 2 1 0 3 0; 1 2 0 0 2; 0 3 1 0 0]); % data
[ii, ~, vv] = find(A);
uniq = accumarray(ii(:), vv(:), [], @(x){unique(x.')});
This gives:
>> celldisp(uniq)
uniq{1} =
1
uniq{2} =
1 2 3
uniq{3} =
1 2
uniq{4} =
1 3
Upvotes: 4