Сводная таблица с дополнительными столбцами - PullRequest
1 голос
/ 22 апреля 2019

Давайте получим двумерный двойной массив, такой как:

% 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 ];

Мне нужно повернуть / сгруппировать по строкам с наивысшими весами для каждого заданного индекса, чего можно достичь с помощью любой сводной таблицы | Функциональность группировки по (например, 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 ]

Как мне поступить, если мне нужно восстановить также идентификатор и столбцы категории?

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

Синтаксис - Matlab, но может быть приемлемо решение с участием других языков (Java, SQL), поскольку они могут быть транскрибированы в Matlab.

1 Ответ

2 голосов
/ 22 апреля 2019

Вы можете использовать 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.

...