Gaze
Gaze

Reputation: 13

How to remove extra duplicated elements in each row of a matrix in matlab?

Let's say I have a matrix

A = [2 3 2 5 6 7 2; 
     1 2 5 4 5 6 7; 
     7 5 3 9 8 1 2];

How do I remove 2s and keep one 2 in the first row and keep only one 5 in the second row?

Upvotes: 0

Views: 42

Answers (2)

Luis Mendo
Luis Mendo

Reputation: 112769

The result can't be a matrix anymore, because each row will have a different length. You can obtain the result as a cell array of row vectors as follows:

B = mat2cell(A, ones(size(A,1),1)); %// convert matrix to cell array of its rows
B = cellfun(@(x) unique(x,'stable'), B, 'uniformoutput', 0); %// stably remove duplicates

For your example matrix

A = [2 3 2 5 6 7 2; 
     1 2 5 4 5 6 7; 
     7 5 3 9 8 1 2];

this gives

B{1} =
     2     3     5     6     7
B{2} =
     1     2     5     4     6     7
B{3} =
     7     5     3     9     8     1     2

Upvotes: 4

dan-man
dan-man

Reputation: 2989

If you want to find out which values are duplicates within the row, you can do something like this:

[vals, col_idx]  = sort(A,2);
idx = bsxfun(@plus,(col_idx-1)*size(A,1), (1:size(A,1))');
is_duplicate(idx(:,2:end)) = vals(:,1:end-1) == vals(:,2:end);
is_duplicate = reshape(is_duplicate, size(A));

is_duplicate =

 0     0     1     0     0     0     1
 0     0     0     0     1     0     0
 0     0     0     0     0     0     0

From there, it depends what outcome you are looking for. You could set the duplicates to NaN or some other value, or you could set them to NaN, but then shift them to the end of the row, using something like the following:

col_idx = cumsum(~is_duplicate, 2);
idx = bsxfun(@plus,(col_idx-1)*size(A,1), (1:size(A,1))');
A_new = nan(size(A));
A_new(idx(~is_duplicate)) = A(~is_duplicate);

A_new =

 2     3     5     6     7   NaN   NaN
 1     2     5     4     6     7   NaN
 7     5     3     9     8     1     2

Upvotes: 1

Related Questions