Одним из решений является репликация индексов строк в labels
и добавление еще одного столбца индексов столбцов.Затем вы можете изменить X
в вектор-столбец и применить accumarray
один раз:
labels = [repmat(labels(:),nCols,1) ... % Replicate the row indices
kron(1:nCols,ones(1,numel(labels))).']; % Create column indices
totals = accumarray(labels,X(:)); % I used "totals" instead of "means"
Как это работает ...
A = accumarray(subs,val)
для вектора-столбца subs
и вектора val
работает путем добавления числа в val(i)
к итогу в строке subs(i)
в векторе выходного столбца A
.Однако subs
может содержать не только индексы строк.Он может содержать индексы индексов для нескольких измерений, которым можно присвоить значения в выходных данных.Эта функция позволяет обрабатывать ввод val
, который является матрицей, а не вектором.
Во-первых, вход для val
может быть преобразован в вектор столбца с помощью оператора двоеточия X(:)
.Затем, чтобы отслеживать, какой столбец в выходных данных должен содержать значения в X(:)
, мы можем изменить ввод subs
, добавив дополнительный индекс столбца.Чтобы проиллюстрировать, как это работает, я буду использовать эти примеры входных данных:
labels = [3; 1; 1];
X = [1 2 3; ...
4 5 6; ...
7 8 9];
nCols = 3
А вот как выглядят переменные в приведенном выше коде:
labels = 3 1 X(:) = 1 totals = 11 13 15
1 1 4 0 0 0
1 1 7 1 2 3
3 2 2
1 2 5
1 2 8
3 3 3
1 3 6
1 3 9
Обратите внимание, дляНапример, значения 1 4 7
, которые изначально были в первом столбце X
, будут накапливаться только в первом столбце выходных данных, что обозначено значениями в первых трех строках второго столбца labels
.Результирующий вывод должен быть таким же, как и при использовании кода в вопросе, где вы перебираете каждый столбец для выполнения накопления.