I have a cell array c
of equal-sized arrays, i.e. size(c{n}) = [ m l ... ]
for any n
. How can I get the mean
values (averaging over the cell array index n
) for all array elements in one sweep? I thought about using cell2mat
and mean
but the former does not add another dimension but changes l
to l*n
. And looping manually of course takes like forever...

- 125,304
- 15
- 256
- 359

- 25,759
- 22
- 127
- 221
-
question extended to [weighted averaging](http://stackoverflow.com/questions/5231406/how-to-calculate-the-weighted-average-over-a-cell-array-of-arrays "How to calculate the weighted average over a cell-array of arrays?") – Tobias Kienzler Mar 09 '11 at 09:50
6 Answers
If all of your arrays are the same size, it makes more sense to store them in a matrix rather than a cell array. That makes it easier to perform operations across them, like taking the mean. You can convert your data to a matrix using the functions NDIMS and CAT:
dim = ndims(c{1}); %# Get the number of dimensions for your arrays
M = cat(dim+1,c{:}); %# Convert to a (dim+1)-dimensional matrix
meanArray = mean(M,dim+1); %# Get the mean across arrays

- 125,304
- 15
- 256
- 359
-
Thanks, I extended this now for [weighted averaging](http://stackoverflow.com/questions/5231406/how-to-calculate-the-weighted-average-over-a-cell-array-of-arrays/5244433#5244433) – Tobias Kienzler Mar 09 '11 at 10:34
If you have a Higher version of matlab, It can be done by 'cellfun' function. This can treat the cells with unequal size array.
C = {1:10, [2; 4; 6], []};
Cmeans = cellfun(@mean, C)
Cmeans =
5.5000 4.0000 NaN
Reference: https://groups.google.com/forum/?fromgroups=#!topic/comp.soft-sys.matlab/S_hyHxy11f0

- 103
- 2
- 6
-
Thanks - I can't helping wondering where the "fun" in `cellfun` occurs :-P I guess this would also make sense to use for my [weighted averaging extension](http://stackoverflow.com/a/5244433/321973) then – Tobias Kienzler Sep 11 '12 at 09:10
I found an easy way to find the mean values within a Cell array on the following link: http://www.gomatlab.de/cellfun-t25114.html
May x
be the cell. Then:
var_mean = cellfun(@mean, x, 'UniformOutput', false); %columnwise mean value
var_mean = cellfun(@(in) mean(in(:)), x); %% mean value of the total "subcell"

- 1,466
- 3
- 17
- 38

- 23
- 3
-
Thanks! `cellfun` has already been mentioned in [this answer](http://stackoverflow.com/a/12358340/321973), but the `UniformOutput` switch might be helpful for some. Also: Welcome to StackOverflow! Please take a minute to read the [about](http://stackoverflow.com/about) site to learn how this site differs from a usual forum - also, you get a shiny badge for that :D – Tobias Kienzler Nov 06 '13 at 09:43
You're on the right track. Use CELL2MAT to convert your cell array to a numerical array and then RESHAPE to construct a three dimensional matrix. You can then calculate the mean using the MEAN function with the dimension argument:
>> c = {[1 2 3; 4 5 6] [7 8 9; 12 13 14]} c = [2x3 double] [2x3 double] >> mean(reshape(cell2mat(c), [2, 3, 2]), 3) ans = 4 5 6 8 9 10

- 7,094
- 2
- 33
- 48
-
+1 or more generally `mean(reshape(cell2mat(c), [ size(c{1}), length(c) ]), ndims(c{1})+1)` – Tobias Kienzler Mar 07 '11 at 10:54
-
I wish I could accept two answers... I picked gnovice's one because I could copy-paste it directly, but your solution works equally well – Tobias Kienzler Mar 07 '11 at 11:31
This just loops through the cell and means the array down until it is a singleton. It doesn't take that long, this is 40 million floats being meaned, takes 1 second.
function n = big_mean
tic
c = cell(1000);
for ii = 1:length(c)
c{ii} = rand(8,7,6,5,4,3,2);
end
n = all_cells(c);
toc
end
function n = all_cells(c)
n = zeros(length(c),1);
for ii = 1:length(c)
n(ii) = cell_mean(c{ii});
end
n = mean(n);
end
function n = cell_mean(n)
while length(size(n))~=2
n = mean(n);
end
end
Elapsed time is 1.042459 seconds.
ans =
0.4999

- 2,365
- 4
- 21
- 27
-
sorry I may have asked my question a bit too vague, I don't want the total average over all elements, but preserving the underlying array structure obtain the per element average, see e.g. [b3's answer](http://stackoverflow.com/questions/5197597/how-to-average-over-a-cell-array-of-arrays/5197697#5197697) – Tobias Kienzler Mar 07 '11 at 10:57
-
thanks for your other comments, but sometimes, it is hard to rearrange the data or change the way they are saved. For those of you who have this issue, here is the solution, Enjoy.
a=0;
MyCellAddFun=@(Input) a*eye(size(Input))+Input;
temp=arrayfun(@(ind) MyCellAddFun(CellData{ind}),1:length(CellData),'uniformoutput',false);
answer=temp{end}

- 11,997
- 8
- 49
- 58