Reputation: 189836
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
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