Jason S
Jason S

Reputation: 189836

Matlab: "grouping mean"

Suppose I have the vectors:

 y = [1 1.01 1.02 1.03 2 2.01 2.02 3 3.01 3.02 3.03];
 c = [0 0    0    0    1 1    1    2 2    2    2   ];

Is there a vectorized way to get a "grouping mean", that is, the mean value of y for each unique value of c? (This is a simplified example; I have something similar but the vector size is in the thousands and there are hundreds of values of c)

I can do it in a for-loop, just wondering if it could be vectorized. Here's my for-loop implementation:

function [my,mc] = groupmean(y,c)
my = [];
mc = [];
for ci = unique(c)'
    mc(end+1) = ci;
    my(end+1) = mean(y(c==ci));
end

Upvotes: 2

Views: 1142

Answers (1)

Sam Roberts
Sam Roberts

Reputation: 24127

Short answer:

>> y = [1 1.01 1.02 1.03 2 2.01 2.02 3 3.01 3.02 3.03];
>> c = [0 0    0    0    1 1    1    2 2    2    2   ];
>> groupmeans = accumarray(c'+1,y',[],@mean)
groupmeans =
        1.015
         2.01
        3.015

To explain the above: accumarray is a bit cryptic, but extremely useful and worth getting to know (and very fast). The first input is a vector (they need to be column vectors, which is why it's c' and y') that groups the rows of the second input vector. The elements need to be positive integers (for some reason), which is why I've added 1 to c'. The last input is a handle to a function that is applied as an accumulator to each group of the values in y.

Hope that makes sense! If not, doc accumarray :)

Upvotes: 6

Related Questions