0

Suppose I have matrix A. 1st column is "group". Then I want to calculate the average of 2nd column for each group. So I want to create B.

A=
 1  2
 1  3
 2  4
 2  2

B=
 1  2.5
 2  3

The best thing I did until now is to construct a long for and if loop and use average function to get to B.

But I guess there will be more simple method. Is there?

user3123767
  • 1,115
  • 3
  • 13
  • 22

1 Answers1

2

I hadn't used accumarray before, so due to the comment by @Dan I decided to give it a try.

At first I tried a naive version and used histc to count occurrences to get the desired mean values... (Note that accumarray will sort the output the same order as unique, so mean will be calculated correctly)

%// Naive version
ua = unique(A(:,1)); %// use as histc bins (or sorted "group" values)
result = accumarray(A(:,1), A(:,2)) ./ histc(A(:,1), uA);

Here, accumarray operates by summing over all entries in A(:,2) corresponding to identical subscripts in A(:,1).

But then I realised that by passing the optional fun argument to accumarray changing "summing" to "mean", you can do this as a one-liner:

%// one-liner
result = accumarray(A(:,1), A(:,2), [], @mean);
mikkola
  • 3,376
  • 1
  • 19
  • 41
  • accumarray is the way to go if you just need to aggregate an array. If you need to aggregate up full rows of a data matrix, you may want to checkout [this thread](http://stackoverflow.com/questions/33635984/time-series-aggregation-efficiency). I'll give a shameless plug for my mex function over there :P I didn't know about accumarray at the time, but I basically wrote accumarray for matrices. – Matthew Gunn Nov 24 '15 at 07:13
  • @MatthewGunn Some more alternatives: http://stackoverflow.com/questions/4350735/is-there-an-accumarray-that-takes-matrix-as-val and http://stackoverflow.com/questions/16086874/matlab-find-and-apply-function-to-values-of-repeated-indices – Dan Nov 24 '15 at 08:29
  • @mikkola Thank you very much!! – user3123767 Nov 25 '15 at 05:40