【问题标题】:Grouping elements of one column of matrix according to values of another column into cell array根据另一列的值将矩阵的一列的元素分组到元胞数组中
【发布时间】:2015-04-09 09:30:39
【问题描述】:

一段时间以来,我一直在尝试想出一个聪明的方法来做到这一点。给定一个具有以下结构的矩阵(或单元格):

A = [-1  1 
     -1  2 
      1  3 
      3  5
      2  3 
      2  4 
      2  7  
      4  5 
      5  6 
      6  7 
      7 -2 ]

(请注意,上述矩阵/单元格在两列中均未排序且包含负数)。

如何按特定列的唯一值对其进行分组。例如。按第二列分组的所需输出类似于:

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]

提前致谢!

【问题讨论】:

  • 你说的是矩阵(或单元格) - 这差别很大!
  • 这个B{-2} = [7]是无效的matlab语法。
  • 在上面的代码中,您将 indx 显示为负数,但作为 matlab 语法,您不能使用小于或等于 0 作为 indx。

标签: matlab matrix grouping


【解决方案1】:

你可以使用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]

【讨论】:

  • 也许使用'stable'
  • @Divakar 我虽然谈到了它,但我不确定它是否是 OP 想要的,但我会包含它。因为在他的输出中它是排序的。
  • 即使我不确定,我想仔细检查预期的输出可能会更好。
  • @Divakar,他想要排序后的版本,但最后是否定的版本
  • tehwaywewalk & @Divakar 这太棒了!非常感谢!
【解决方案2】:

怎么样:

[group, ~, subs] = unique(A(:,2))
B = accumarray(subs, A(:,1), [], @(x){x'})

结果

B= 

    [  7]
    [ -1]
    [ -1]
    [2,1]
    [  2]
    [4,3]
    [  5]
    [2,6]

并且groupB 的索引与它所代表的组的编号相匹配

此外,如果您对订单有兴趣,那么您可以这样做:

[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

【讨论】:

    猜你喜欢
    • 2013-09-20
    • 2018-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多