A more general approach would employ unique
to find the unique index values:
[U, ix, iu] = unique(x(:, 1));
and then accumarray
:
[c, r] = meshgrid(1:size(x, 2), iu);
y = accumarray([r(:), c(:)], x(:), [], @mean);
Explanation
The input values to process are actually the second parameter of accumarray
.
The first parameter of accumarray
is a matrix, each row being a set of indices in the (accumulated) output matrix, and it corresponds to a value from the matching row in the vector given as the second parameter.
Think of the output as a cell array. The second parameters are the input values, and each row in the first parameter tells in which cell of the output matrix accumarray
should store the corresponding input value. When output "cell array" is finished, a function (mean
in our case) is applied to each cell.
Example
Here's a short example with a smaller matrix:
x = [27, 10, 8;
28, 20, 10;
28, 30, 50];
We find the unique values by:
[U, ix, iu] = unique(x(:, 1));
Vector U
stores the unique values, and iu
indicates which index of the value associated with each row (note that in this solution we have no use for ix
). In our case we get that:
U =
27
28
iu =
1
2
2
Now we apply accumarray
:
[c, r] = meshgrid(1:size(x, 2), iu);
y = accumarray([r(:), c(:)], x(:), [], @mean);
The fancy trick with meshgrid
and [r(:), c(:)]
produces a set of indices:
[r(:), c(:)] =
1 1
2 1
2 1
1 2
2 2
2 2
1 3
2 3
2 3
and these are the indices for the input values x(:)
, which is a column-vector equivalent of x
:
x(:) =
27
28
28
10
20
30
8
10
50
The process of accumulation:
- The first value 27 goes to cell <1,1> in the output matrix.
- The second value 28 goes to cell <2,1> in the output matrix.
- The third value 28 goes to cell <2,1> in the output matrix.
See what just happened? Both values 28 get accumulated in the same cell (and eventually they will be averaged). The process continues:
- The fourth value 10 goes to cell <1,2> in the output matrix.
and so on...
Once all values are stored in cells, the function mean
is applied on each cell and we get the final output matrix:
y =
27 10 8
28 25 30