Вы можете использовать splitapply
(немного дружелюбный младший брат accumarray
):
% Your example
data = rand(20,1000); % generate data
bins = [5 10 5]; % given size of bins
% Calculation
bins = repelem(1:numel(bins), bins).'; % Bin sizes to group labels
binned_data = splitapply( @mean, data, bins ); % splitapply for calculation
Строки binned_data
- ваши a
, [115 ] и c
.
Среднее значение может быть применено до расщепления, которое сводит данные в вектор, а затем accumarray
[ 116] можно использовать:
binned_data = accumarray(repelem(1:numel(bins), bins).', mean(data,2), [], @(x){x.'});
accumarray
1 sup> не работает с матричными данными. Но вы можете использовать sparse
, который автоматически накапливает значения данных, соответствующие тем же индексам:
ind_rows = repmat(repelem((1:numel(bins)).', bins), 1, size(data,2));
ind_cols = repmat(1:size(data,2), size(data,1), 1);
binned_data = sparse(ind_rows, ind_cols, data);
binned_data = bsxfun(@rdivide, binned_data, bins(:));
binned_data = num2cell(binned_data, 2).';
Но splitapply
делает. См. @ Ответ Вулфи . SUP>
Вы можете использовать умножение матриц:
r = 1:numel(bins);
result = (r.' == repelem(r,bins)) * data .* (1./bins(:));
Если вы хотите выводить как ячейку:
result = num2cell(result,2);
Для больших матриц лучше использовать разреженную матрицу:
[ 112] Примечание: в предыдущих версиях MATLAB вы должны использовать bsxfun
:
result = bsxfun(@times,bsxfun(@eq, r.',repelem(r,bins)) * data , (1./bins(:)))
Вот результат синхронизации для трех предложенных методов в Octave:
Умножение матриц:
0.00197697 seconds
Accumarray:
0.00465298 seconds
Cellfun:
0.00718904 seconds
РЕДАКТИРОВАТЬ: Для матрицы 200 x 100000:
Умножение матриц: [ 1120]
0.806947 seconds sparse: 0.2331 seconds
Accumarray:
0.0398011 seconds
Cellfun:
0.386079 seconds
Вы также можете использовать простой цикл for, я не вижу, как другая функция может быть быстрее в этом случае. Функция mean
должна в любом случае читать каждое значение, чтобы ...
for ii = 1:numel(start_bins)
res{ii} = mean(data(start_bins(ii):end_bins(ii),:),1);
end
Я не собираюсь разбивать ячейку на несколько переменных, поскольку ячейка предназначена именно для этого.