具有附加列的数据透视表

Posted

技术标签:

【中文标题】具有附加列的数据透视表【英文标题】:Pivot Table with Additional Columns 【发布时间】:2019-04-21 22:12:33 【问题描述】:

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

% 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 和 Category 列,我应该如何进行?

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

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

【问题讨论】:

如果出现平局,是否应该保留所有最大化的行?第一个? 我对这种情况没有任何规范。可能是最简单的实现方式。 【参考方案1】:

您可以将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

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


使用上述解决方案,如果每个组有多个最大化行所有都会生成。要只保留第一个,请将最后一行替换为

result = cell2mat(cellfun(@(c) c(1,:), result, 'uniformoutput', false));

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

【讨论】:

以上是关于具有附加列的数据透视表的主要内容,如果未能解决你的问题,请参考以下文章

具有动态列的 MySQL 数据透视表查询

具有两行到列的数据透视表

具有多个值列的数据透视表

SQL Server 中具有动态列的数据透视表

如何获取附加数据透视表的数据?

Kohana 3.0.x ORM:读取数据透视表中的其他列