【问题标题】:How to calculate the weighted average over a cell-array of arrays?如何计算数组单元阵列的加权平均值?
【发布时间】:2011-07-11 00:36:18
【问题描述】:

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. weight = 1(或任何常数)=> 返回通常的平均值
  2. numel(weight) == length(c) => 权重是每个单元格元素 c{n}(但对于固定 n 的每个数组元素相等)
  3. numel(weight) == numel(cell2mat(c)) => 每个数组元素都有自己的权重...

案例 1 很简单,案例 3 不太可能发生,所以目前我对案例 2 感兴趣:如何将权重转换为数组,以使 M.*weight 在上述总和中具有正确的维度?当然,我们也很欣赏显示另一种获得加权平均值的方法的答案。


edit事实上,如果权重与 c 具有相同的结构,情况 3 甚至比情况 1 更简单(多么重言式,道歉)

这是我对案例 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)

【问题讨论】:

  • 你有没有想过把它变成一个函数,使用varargin并根据上面列出的三个条件解析weight参数?
  • 对于情况 (2),查看 sub2ind 以便将 weight 向量和 c 单元格都转换为线性索引会很有趣。您将失去此计算的结构,但无论如何您都在计算平均值。只是大声思考......
  • @Phonon: re 1) 是的,这就是它周围的框架,现在我只需要弄清楚如何重塑/repmat/...?每个案例的正确重量。重新 2) 我想我没有明白你关于 sub2int 的观点,但也澄清了我想要的:meanArray 的结构应与c{1} 的结构相同,即我不希望一个平均值超过除了每个数组位置之外的所有元素

标签: arrays matlab cell weighted-average


【解决方案1】:

在熟悉了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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-10-04
    • 1970-01-01
    • 2020-12-07
    • 1970-01-01
    • 2017-01-06
    • 2023-03-24
    • 2021-11-24
    • 1970-01-01
    相关资源
    最近更新 更多