Как рассчитать средневзвешенное значение по массиву ячеек? - PullRequest
0 голосов
/ 08 марта 2011

В обобщении моего предыдущего вопроса , как можно выполнить средневзвешенное значение по элементам ячейки (которые являются и должны оставаться самими массивами)?


Я бы начал сизменив ответ gnovice следующим образом:

dim = ndims(c{1});          %# Get the number of dimensions for your arrays
M = cat(dim+1,c{:});        %# Convert to a (dim+1)-dimensional matrix
meanArray = sum(M.*weigth,dim+1)./sum(weigth,dim+1);  %# Get the weighted mean across arrays

И перед этим убедитесь, что weight имеет правильную форму.Я думаю, что нужно учесть три случая:

  1. weight = 1 (или любая константа) => вернуть обычное среднее значение
  2. цифра (вес) == длина(c) => вес для каждого элемента ячейки c {n} (но равным для каждого элемента массива при фиксированном n)
  3. цифра (вес) == цифра (cell2mat (c)) => каждый массив -элемент имеет свой собственный вес ...

Случай 1 прост, а случай 3 маловероятен, поэтому в данный момент меня интересует случай 2: как я могу преобразовать вес в массив, чтобыM.*weight имеет правильные размеры в сумме выше?Конечно, также приветствуется ответ, который показывает другой способ получения взвешенного усреднения.


edit На самом деле, случай 3 еще более тривиален (что за тавтология, извинения) чем в случае 1, если вес имеет ту же структуру, что и c.

Вот пример того, что я имею в виду для случая 2:

c = { [1 2 3; 1 2 3], [4 8 3; 4 2 6] };
weight = [ 2, 1 ];

должен вернуть

meanArray = [ 2 4 3; 2 2 4 ]

(например, для первого элемента (2 * 1 + 1 * 4) / (2 + 1) = 2)

1 Ответ

1 голос
/ 09 марта 2011

После ознакомления с REPMAT , вот мое решение:

function meanArray = cellMean(c, weight)
% meanArray = cellMean(c, [weight=1])
% mean over the elements of a cell c, keeping matrix structures of cell
% elements etc. Use weight if given.

% based on http://stackoverflow.com/q/5197692/321973, courtesy of gnovice
% (http://stackoverflow.com/users/52738/gnovice)
% extended to weighted averaging by Tobias Kienzler
% (see also http://stackoverflow.com/q/5231406/321973)

dim = ndims(c{1});          %# Get the number of dimensions for your arrays
if ~exist('weight', 'var') || isempty(weight); weight = 1; end;
eins = ones(size(c{1})); % that is german for "one", creative, I know...
if ~iscell(weight)
    % ignore length if all elements are equal, this is case 1
    if isequal(weight./max(weight(:)), ones(size(weight)))
        weight = repmat(eins, [size(eins)>0 length(c)]);
    elseif isequal(numel(weight), length(c)) % case 2: per cell-array weigth
        weight = repmat(shiftdim(weight, -3), [size(eins) 1]);
    else
        error(['Weird weight dimensions: ' num2str(size(weight))]);
    end
else % case 3, insert some dimension check here if you want
    weight = cat(dim+1,weight{:});
end;

M = cat(dim+1,c{:});        %# Convert to a (dim+1)-dimensional matrix
sumc = sum(M.*weight,dim+1);
sumw = sum(weight,dim+1);
meanArray = sumc./sumw;  %# Get the weighted mean across arrays
...