我有一个包含重复数字的向量:
[1 1 1 1 5 5 5 5 93 93 93 6 6 6 6 6 6]
等等。我想要做的是将相似的值(1,5等)分组。我希望将每个唯一值放在一个大矩阵的行中,例如:
[ 1 1 1 1 0 0
5 5 5 5 0 0
93 93 93 0 0 0
6 6 6 6 6 6]
我不知道唯一值的最大出现次数,因此可以创建一个包含大量列的初始零矩阵(我确信它大于唯一值的最大出现次数)值)。 任何帮助都非常感谢。
答案 0 :(得分:5)
这个怎么样?
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) )' )
返回:
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
我知道订单不同,那重要吗?否则:
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
或Luis Mendo的答案更短:
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)'
返回:
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
对于那些无聊的人来说,有一个单线解决方案:
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)))})
或者是一个几乎可爱的双人班轮:
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)})
只是为了好玩;)
答案 1 :(得分:5)
矢量化解决方案(无循环):
x = [1 1 1 1 5 5 5 5 93 93 93 6 6 6 6 6 6]; %// data
ind = [find(diff(x)) numel(x)]; %// end of each run of equal values
values = x(ind); %// unique values (maintaining order)
count = diff([0 ind]); %// count of each value
result = bsxfun(@le, meshgrid(1:max(count),1:numel(values)), count.'); %'// mask
result = bsxfun(@times, result, values.'); %'// fill with the values
编辑:
避免第二个bsxfun
的替代程序:
x = [1 1 1 1 5 5 5 5 93 93 93 6 6 6 6 6 6]; %// data
ind = [find(diff(x)) numel(x)];
values = x(ind); %// unique values (maintaining order)
count = diff([0 ind]); %// count of each value
mask = bsxfun(@le, ndgrid(1:max(count),1:numel(values)), count);
result = zeros(size(mask)); %// pre-allocate and pre-shape (transposed) result
result(mask) = x; %// fill in values
result = result.';
答案 2 :(得分:2)
这可能是一种方法 -
%%// Input
array1 = [1 1 1 1 5 5 5 5 93 93 93 6 6 6 6 6 6];
%// Main Processing
id = unique(array1,'stable'); %//Find the unique numbers/IDs
mat1 = zeros(numel(id),nnz(array1==mode(array1))); %%// Create a matrix to hold the final result
for k=1:numel(id)
extent_each_id = nnz(array1==id(k)); %%// Count of no. of occurances for each ID
mat1(k,1:extent_each_id)=id(k); %%// Starting from the left to the extent for each ID store that ID
end
给予 -
mat1 =
1 1 1 1 0 0
5 5 5 5 0 0
93 93 93 0 0 0
6 6 6 6 6 6