Count how many times a number appears in a matrix and assign that increasing value to a new matrix

3 views (last 30 days)
I have a 32 x 6 matrix consisting of repeats of 1-16 in each column in a specific order, e.g., :
X = [6 1 1 8 16 1
2 16 6 6 9 8
7 9 10 13 1 16
15 5 3 6 3 11
9 3 13 1 7 12
10 11 8 7 5 7
etc etc];
So given this set up, each instance of 1 - 16 will appear 12 times, twice in each column. What I need to do is create another matrix of the same size, indexing for each number where those repeats are occurring. So for example, if a column looked like this:
1
3
3
2
1
it would return:
1
1
2 (the second time 3 is appearing)
1
2 (the second time 1 is appearing)
I was thinking about using some kind of count function for each number and then perhaps applying a multiplication to it? Would be fine if these had to be separate matrices for each of the 16 numbers if that makes it any simpler. Any suggestions?

Accepted Answer

Andrei Bobrov
Andrei Bobrov on 2 Oct 2012
Edited: Andrei Bobrov on 2 Oct 2012
out = ones(size(X));
for j1 = 1:size(X,2)
[u,i1] = unique(X(:,j1));
id = i1(histc(X(:,j1),u) > 1);
out(id,j1) = out(id,j1) + 1;
end
or
out = zeros(size(X));
for j1 = 1:size(X,2)
b = unique(X(:,j1));
for jj = 1:numel(b)
t = abs(X(:,j1) - b(jj)) < eps(100);
out(t,j1) = 1:nnz(t);
end
end
  2 Comments
Lauren Shone
Lauren Shone on 2 Oct 2012
Thanks, this produces a beautiful result on a column by column basis, but do you know if there is a way to keep the cumulation going across columns? i.e., once you move to the second column the indexes become 3 and 4, then for the third column 5 and 6 etc? Alternatively, do you think it would work to reshape X and try and apply a similar function to what you have suggested that works it way down the one column if going across doesn't work? Have tried a few variations but nothing coming up so far.
Lauren Shone
Lauren Shone on 2 Oct 2012
Although on second thought, given the small size of the matrix I can easily just do a more manual replace column by column, Thanks again!

Sign in to comment.

More Answers (2)

Matt J
Matt J on 2 Oct 2012
Edited: Matt J on 2 Oct 2012
This relies on the assumption that each number appears exactly twice in each column (as in the posted example):
out = ones(size(X));
for ii = 1:size(X,2)
[~,idx] = unique(X(:,ii),'last');
out(idx,ii)=2;
end

Azzi Abdelmalek
Azzi Abdelmalek on 2 Oct 2012
Edited: Azzi Abdelmalek on 2 Oct 2012
A=[]
for k=1:6
A=[A [randperm(16)' ;randperm(16)']]
end
% for the above example
idx=[];
for k=1:16
[ii,~]=find(A==k)
idx=[idx;reshape(ii,2,[])];
end

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!