如何计算阵列单元阵列的加权平均值?

如何计算阵列单元阵列的加权平均值?

问题描述:

my previous question的概括中,如何执行单元格元素的加权平均值(它们本身仍然是数组)并且应该保留它们本身?如何计算阵列单元阵列的加权平均值?


我想通过修改gnovice's answer这样开始:

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. 重量= 1(或任何常数)=>返回通常的平均值
  2. numel(重量)==长度(C)=>重量的是每个细胞元c {N}(但等于用于固定n各自数组元素)
  3. numel(重量)== numel(cell2mat(C))=>每个阵列元件具有其自身的重量...

第一种情况很容易,第三种情况不太可能发生,所以此刻我对情况2感兴趣:如何将权重转换为数组,使得M.*weight在上述总和中具有正确的尺寸?当然,也可以通过另一种方式获得加权平均值的答案。


编辑事实上,壳体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)

+0

你有没有想过按照上面列出的三个标准使用'varargin'和解析'weight'参数来使它成为一个函数? – Phonon 2011-03-08 15:01:43

+0

对于情况(2),为了将'weight'向量和''c'单元转换为线性索引,查看'sub2ind'会很有趣。你将失去这个计算的结构,但你仍然在计算一个平均值。只是想着大声.​​..... – Phonon 2011-03-08 15:06:32

+0

@Phonon:re 1)是的,这是围绕它的框架,现在我只需要弄清楚如何重塑/ repmat/...?每个案件的重量正确。 2)我认为我没有明白你对sub2int的意见,而是为了澄清我想要的:'meanArray'的结构应该与'c {1}'的结构相同,即我不想要一个平均在所有元素上,但是对于每个阵列位置单独 – 2011-03-09 09:26:47

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