Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
419 views
in Technique[技术] by (71.8m points)

average - MATLAB Accumarray weighted mean

So I am currently using 'accumarray' to find the averages of a range of numbers wich correspond to matching ID's. Ex Input:

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

My current code finds the unweighted average of the above values, using the ID as the 'seperator' so that I don't get the average for all of the values together as one number, but rather seperate results for just values which have corresponding ID's. EX Output:

ID----Value
1     224.66
2     402.66

To achieve this I am using this code:

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

With StarData2 being the input of the function. This is working perfectly for my purposes until now, I need to know if accumarray can be made to give me a weighted average, such that each point in app (before the average is found) can be assigned a weight or that the @mean can be replaced with a function that can achieve this. The new input will look like this:

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

The new code must do the sum(val(i)*weight(i))/sum(weight) instead of just the standard mean. Thanks for any assistance.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You can use the row index as the "vals" (second input to accumarray) and define your own function that does the weighted mean on group of the data:

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)

Demonstration

Starting with data (the new input with your weights) and your unique command:

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');

The accumarray usage is as follows (redefine WeightedMeanFcn every time you change 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

Checking manually, with the first group:

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...