MATLAB Accumarray加权平均值

时间:2014-04-01 16:48:52

标签: matlab average mean accumarray

所以我目前正在使用' accumarray'找到与匹配ID相对应的一系列数字的平均值。 Ex输入:

ID----Value
1     215
1     336
1     123
2     111
2     246
2     851

我的当前代码使用ID作为'分隔符来查找上述值的未加权平均值。因此,我不能将所有值的平均值作为一个数字得到,而是仅对具有相应ID的值进行单独的结果。 EX输出:

ID----Value
1     224.66
2     402.66

为了达到这个目的,我使用的是这段代码:

[ID, ~, Groups] = unique(StarData2(:,1),'stable');
app = accumarray(Groups, StarData2(:,2), [], @mean);

使用StarData2作为函数的输入。这对我的目的来说是完美的,直到现在,我需要知道是否可以让accumarray给我一个加权平均值,这样app中的每个点(在找到平均值之前)都可以赋予权重或者@mean可以被替换为可以实现此目的的功能。新输入将如下所示:

ID----Value----Weight
1     215     12
1     336     17
1     123     11
2     111     6
2     246     20
2     851     18

新代码必须总和(val(i)* weight(i))/ sum(weight)而不仅仅是标准均值。感谢您的帮助。

4 个答案:

答案 0 :(得分:7)

您可以将行索引用作" vals" (second inputaccumarray)并定义自己的函数,对数据组进行加权平均值:

Weights = data(:,3); Vals = data(:,2); % pick your columns here
WeightedMeanFcn = @(ii) sum(Vals(ii).*Weights(ii))/sum(Weights(ii));
wmeans = accumarray(Groups, 1:numel(Groups), [], WeightedMeanFcn)

<强>示范

data(带权重的新输入)和unique命令开始:

data = [1,215,12; 1,336,17; 1,123,11; 2,111,6; 2,246,20; 2,851,18];
[ID, ~, Groups] = unique(data(:,1),'stable');

accumarray用法如下(每当更改WeightedMeanFcn时重新定义data !):

>> Weights = data(:,3); Vals = data(:,2); % pick your columns here
>> WeightedMeanFcn = @(ii) sum(Vals(ii).*Weights(ii))/sum(Weights(ii));
>> app = accumarray(Groups, 1:numel(Groups), [], WeightedMeanFcn)
app =
  241.1250
  475.0909

使用第一组手动检查:

ig = 1;
sum(data(Groups==ig,2).*data(Groups==ig,3))/sum(data(Groups==ig,3))
ans =
  241.1250

答案 1 :(得分:1)

您可以非常轻松地直接计算加权平均值或许多其他函数,而不是使用accumarray

nIDs = length(unique(ID));
WeightedMean = zeros(nIDs, 1);

for ii = 1:nIDs
    iID = (ID == ii);
    WeightedMean(ii) = (Value(iID)' * Weight(iID)) / sum(Weight(iID));
end

您是否希望通过accumarray执行此操作的具体原因?

答案 2 :(得分:1)

@Naveh - 通常,建议避免在Matlab中使用循环。 具体来说,如果你有很多组的大量数据 - 它可能会很慢。

使用accumarray是可行的方法,但是如@chappjc所建议的那样定义索引的函数是容易出错的,因为为了被匿名函数捕获,你必须确保该

  

数据不是WeightedMeanFcn的输入。它必须在之前定义   定义WeightedMeanFcn,

正如@chappjc在评论中所说的那样。

要克服此问题的轻微修改是使用accumarray两次:

Weights = data(:,3); Vals = data(:,2); % pick your columns here    
app = accumarray(Groups, Weights.*vals, [], @mean)./accumarray(Groups, Weights, [], @mean);

有时您可能需要将[]参数替换为所需输出的大小。

答案 3 :(得分:-1)

您要计算的不是加权平均值,而是加权直方图 可以找到here的加权直方图的mex实现。虽然,accumarray是安全的方式。