根据另一列的值将矩阵的一列元素分组到元胞数组中
Grouping elements of one column of matrix according to values of another column into cell array
一段时间以来,我一直在尝试想出一种聪明的方法来做这件事。给定具有以下结构的矩阵(或单元格):
A = [-1 1
-1 2
1 3
3 5
2 3
2 4
2 7
4 5
5 6
6 7
7 -2 ]
(注意上面的matrix/cell两列都是未排序的,包含负数)。
如何根据特定列的唯一值对其进行分组。例如。按第二列分组所需的输出类似于:
B{1} = [-1]
B{2} = [-1]
B{3} = [1,2]
B{4} = [2]
B{5} = [3,4]
B{6} = [5]
B{7} = [2,6]
B{-2} = [7]
提前致谢!
怎么样:
[group, ~, subs] = unique(A(:,2))
B = accumarray(subs, A(:,1), [], @(x){x'})
结果
B=
[ 7]
[ -1]
[ -1]
[2,1]
[ 2]
[4,3]
[ 5]
[2,6]
和 group
将 B
的索引与其代表的组编号相匹配
此外,如果您重视订单,那么您可以这样做:
[group, ~, subs] = unique(A(end:-1:1,2), 'stable');
B = flipud(accumarray(subs, A(end:-1:1,1), [], @(x){x'}));
group = flipud(group);
B =
[ -1]
[ -1]
[1x2 double]
[ 2]
[1x2 double]
[ 5]
[1x2 double]
[ 7]
group =
1
2
3
4
5
6
7
-2
您可以使用 accumarray
:
[~,~,subs] = unique(A(:,2));
values = accumarray(subs,A(:,1),[],@(x) {x});
ofGroup = accumarray(subs,A(:,2),[],@(x) {x(1)});
out = [ofGroup values]
out =
[-2] [ 7]
[ 1] [ -1]
[ 2] [ -1]
[ 3] [2x1 double]
[ 4] [ 2]
[ 5] [2x1 double]
[ 6] [ 5]
[ 7] [2x1 double]
如果您真的坚持您提出的订单,您可以执行以下操作,但我认为没有必要.
% positives
pos = A( A(:,2) >= 0 , :);
[~,~,subs] = unique(pos(:,2));
posvalues = accumarray(subs,pos(:,1),[],@(x) {x});
posofGroup = accumarray(subs,pos(:,2),[],@(x) {x(1)});
% negatives
neg = A( A(:,2) < 0 , :);
[~,~,subs] = unique(neg(:,2));
negvalues = flipud( accumarray(subs,neg(:,1),[],@(x) {x}) );
negofGroup = flipud( accumarray(subs,neg(:,2),[],@(x) {x(1)}) );
out = [posofGroup posvalues; negofGroup negvalues ]
out =
[ 1] [ -1]
[ 2] [ -1]
[ 3] [2x1 double]
[ 4] [ 2]
[ 5] [2x1 double]
[ 6] [ 5]
[ 7] [2x1 double]
[-2] [ 7]
一段时间以来,我一直在尝试想出一种聪明的方法来做这件事。给定具有以下结构的矩阵(或单元格):
A = [-1 1
-1 2
1 3
3 5
2 3
2 4
2 7
4 5
5 6
6 7
7 -2 ]
(注意上面的matrix/cell两列都是未排序的,包含负数)。
如何根据特定列的唯一值对其进行分组。例如。按第二列分组所需的输出类似于:
B{1} = [-1]
B{2} = [-1]
B{3} = [1,2]
B{4} = [2]
B{5} = [3,4]
B{6} = [5]
B{7} = [2,6]
B{-2} = [7]
提前致谢!
怎么样:
[group, ~, subs] = unique(A(:,2))
B = accumarray(subs, A(:,1), [], @(x){x'})
结果
B=
[ 7]
[ -1]
[ -1]
[2,1]
[ 2]
[4,3]
[ 5]
[2,6]
和 group
将 B
的索引与其代表的组编号相匹配
此外,如果您重视订单,那么您可以这样做:
[group, ~, subs] = unique(A(end:-1:1,2), 'stable');
B = flipud(accumarray(subs, A(end:-1:1,1), [], @(x){x'}));
group = flipud(group);
B =
[ -1]
[ -1]
[1x2 double]
[ 2]
[1x2 double]
[ 5]
[1x2 double]
[ 7]
group =
1
2
3
4
5
6
7
-2
您可以使用 accumarray
:
[~,~,subs] = unique(A(:,2));
values = accumarray(subs,A(:,1),[],@(x) {x});
ofGroup = accumarray(subs,A(:,2),[],@(x) {x(1)});
out = [ofGroup values]
out =
[-2] [ 7]
[ 1] [ -1]
[ 2] [ -1]
[ 3] [2x1 double]
[ 4] [ 2]
[ 5] [2x1 double]
[ 6] [ 5]
[ 7] [2x1 double]
如果您真的坚持您提出的订单,您可以执行以下操作,但我认为没有必要.
% positives
pos = A( A(:,2) >= 0 , :);
[~,~,subs] = unique(pos(:,2));
posvalues = accumarray(subs,pos(:,1),[],@(x) {x});
posofGroup = accumarray(subs,pos(:,2),[],@(x) {x(1)});
% negatives
neg = A( A(:,2) < 0 , :);
[~,~,subs] = unique(neg(:,2));
negvalues = flipud( accumarray(subs,neg(:,1),[],@(x) {x}) );
negofGroup = flipud( accumarray(subs,neg(:,2),[],@(x) {x(1)}) );
out = [posofGroup posvalues; negofGroup negvalues ]
out =
[ 1] [ -1]
[ 2] [ -1]
[ 3] [2x1 double]
[ 4] [ 2]
[ 5] [2x1 double]
[ 6] [ 5]
[ 7] [2x1 double]
[-2] [ 7]