Matlab 将向量中的唯一值分组并将其放入矩阵中

Matlab 将向量中的唯一值分组并将其放入矩阵中,matlab,sorting,matrix,indexing,unique,Matlab,Sorting,Matrix,Indexing,Unique,我有一个包含重复数字的向量,如下所示: [1 1 1 5 5 5 5 93 93 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] 我不知道唯一值的最大出现次数,因此可以创建一个包含大量列的初始零矩阵(我确信它大于唯一值的最大出现次数)。 非常感谢您的帮助。这可能是一种方法- %%

我有一个包含重复数字的向量,如下所示:

[1 1 1 5 5 5 5 93 93 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]
我不知道唯一值的最大出现次数,因此可以创建一个包含大量列的初始零矩阵(我确信它大于唯一值的最大出现次数)。
非常感谢您的帮助。

这可能是一种方法-

%%// 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
这个怎么样

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
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
我知道顺序不同,这重要吗?否则:

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

或者是受路易斯·门多的回答的启发,简短一点:

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
     6     6     6     6     6     6
    93    93    93     0     0     0
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,[0y],'replicate','pre'),[0max(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)})
只是为了好玩;)

矢量化解决方案(无循环):

编辑:

避免第二次
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.';

重复的数字是否总是排成一行,如您的示例所示?或者可能是
[1 1 5 1 5…]
?@LouisMendo是的,它们总是排成一行。你必须用
模式替换
中间值@Divakar您的代码运行得非常好,其他解决方案的优点是for循环是avoided@H_Absxfun是矢量化的,但arrayfun和repmat在内部是按元素工作的,不是矢量化的方法。进行运行时比较,使其更清晰一点。@divakary您的代码平均运行0.7秒,而“thewaywewalk”解决方案的运行时间为0.2秒。矢量大小为(73246*1)。@Divakar谢谢!必须使用
bsxfun
两次感觉有点麻烦,尽管它们必须为bsxfun再包含一个功能“letimes:)您能给您的代码添加一些注释吗,我不能完全理解这个问题logic@H_A-很难对所有内容进行评论-但如果您查看了工作区中的所有中间结果,应该会很清楚