带有其他列的数据透视表

时间:2019-04-21 22:12:34

标签: matlab pivot-table

我们有一个二维双精度数组,例如:

% Data: ID, Index, Weight, Category
A0=[1 1121 204 1;...
    2 2212 112 1;...
    3 2212 483 3;...
    4 4334 233 1;...
    5 4334 359 2;...
    6 4334 122 3 ];

对于每个给定的索引,我需要按权重最高的行进行透视/分组,这可以通过任何Pivot Table |分组依据功能(例如pivottable,SQL GROUP BY或MS Excel数据透视表)

% Current Result
A1=pivottable(A0,[2],[],[3],{@max}); % Pivot Table
A1=cell2mat(A1); % Convert to array

>>A1=[1121 204;...
      2212 483;...
      4334 359 ]

如果我还需要恢复ID和类别列,应该如何进行?

% Required Result
>>A1=[1 1121 204 1;...
      3 2212 483 3;...
      5 4334 359 2 ];

语法为Matlab,但是可以接受涉及其他语言(Java,SQL)的解决方案,因为它们可以被转录为Matlab。

1 个答案:

答案 0 :(得分:2)

您可以将splitapply与匿名功能配合使用,如下所示。

grouping_col = 2; % Grouping column
maximize_col = 3; % Column to maximize 
[~, ~, group_label] = unique(A0(:,grouping_col));
result = splitapply(@(x) {x(x(:,maximize_col)==max(x(:,maximize_col)),:)}, A0, group_label);
result = cell2mat(result); % convert to matrix

工作原理splitapply为每个组调用一次匿名函数@(x) {x(x(:,maximize_col)==max(···),:)}。该函数作为输入提供了一个子矩阵,该子矩阵包含具有索引grouping_col的列的相同值的所有行。然后,此功能要做的是保留所有将索引为maximize_col的列最大化的行,并将其打包到单元格中。然后,结果由cell2mat转换为矩阵形式。


使用上述解决方案时,如果每个组有多个最大化行,则会产生所有这些所有行。要仅保留第一一个,请用

替换最后一行
result = cell2mat(cellfun(@(c) c(1,:), result, 'uniformoutput', false));

工作原理:它使用cellfun将匿名函数@(c) c(1,:)应用于每个单元格的内容。该函数仅保留第一行。或者,要保留最后行,请使用@(c) c(end,:)。然后再次使用cell2mat将结果转换为矩阵形式。