I have a vector that contains repeated numbers like so:
[1 1 1 1 5 5 5 5 93 93 93 6 6 6 6 6 6]
and so on. What I want to do is to group the similar values (1's, 5's, etc.). I would like to have each of the unique values in a row of a big matrix, like:
[ 1 1 1 1 0 0
5 5 5 5 0 0
93 93 93 0 0 0
6 6 6 6 6 6]
I don't know the maximum number of occurrence of a unique value, so it is ok to create an initial zero matrix with a large number of columns (that I am sure is bigger than the maximum number of occurrence of a unique value). Any help is highly appreciated.
How about this?
A = [1 1 1 1 5 5 5 5 93 93 93 6 6 6 6 6 6];
[a,b] = hist(A,unique(A))
f = @(x) [ones(1,a(x)) zeros(1,max(a)-a(x))]
X = cell2mat( arrayfun(@(x) {f(x)*b(x)}, 1:numel(b) )' )
returns:
X =
1 1 1 1 0 0
5 5 5 5 0 0
6 6 6 6 6 6
93 93 93 0 0 0
I know the order is different, is that important? Otherwise:
n = hist(A,1:max(A)) % counts how often every number apperas
[a b] = unique(A,'stable') % gets all unique numbers
n = n(a) % correlates count and numbers
f = @(x) [ones(1,n(x)) zeros(1,max(n)-n(x))] % creates the logical index
% vector for every single row
X = cell2mat( arrayfun(@(x) {f(x)*b(x)}, 1:numel(b) )' ) %fills the rows
or inspired by Luis Mendo's Answer a little shorter:
n = hist(A,1:max(A));
a = unique(A,'stable')
n = n(a)
Y = repmat(a',1,max(n)).*bsxfun(@le, cumsum(ones(max(n),numel(n))), n)'
returns:
X =
1 1 1 1 0 0
5 5 5 5 0 0
93 93 93 0 0 0
6 6 6 6 6 6
For the bored people out there, there is a one-line solution:
X = getfield(cell2mat(arrayfun(@(x,y) padarray( padarray(x,[0 y],'replicate','pre'),[0 max(hist(A,1:max(A)))-y],'post'),1:max(A),hist(A,1:max(A)),'uni',0)'),{unique(A,'stable'),2:1+max(hist(A,1:max(A)))})
Or an almost lovely two-liner:
n = hist(A,1:max(A))
X = getfield(cell2mat(arrayfun(@(x,y) padarray( padarray(x,[0 y],'replicate',...
'pre'),[0 max(n)-y],'post'),1:max(A),n,'uni',0)'),...
{unique(A,'stable'),2:1+max(n)})
just for fun ;)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With