Mean of Cells of Cells

So I have cell arrays that contain other cells The structure looks like this:
Cell{X} always contains 3 sub-cells, the first sub-cell always contains a 16x107 matrix, the second one a 16x47 matrix and the third one a 16x147 matrix. These are matrices with those dimensions. I want to take the (nan)mean of all same-sized matrices, in some way that is the intuitive equivalent of this: nanmean(Cell{1:end}{1}), nanmean(Cell{1:end}{2}), nanmean(Cell{1:end}{3}), etc. The mean should be taken along the 1st dimension so I end up with with 3 mean matrices, one 16x107, one 16x47, and one 16x147.
Obviously the above ways don't work ('Bad cell reference operation'). How can I do this without looping through everything and adding them up one by one?
To Clarify:
My data:
Cell_1(cell_1(Matrix),cell_2(Matrix),cell_3(Matrix))
Cell_2(cell_1(Matrix),cell_2(Matrix),cell_3(Matrix))
Cell_3(cell_1(Matrix),cell_2(Matrix),cell_3(Matrix))
Cell_4(cell_1(Matrix),cell_2(Matrix),cell_3(Matrix))
I want to get 3 mean matrices, one of all cell_1(Matrix), one of all cell_2(Matrix), and one of all cell_3(Matrix), where the 3 mean matrices are of size cell_1(Matrix), cell_2(Matrix), and cell_3(Matrix). I do not want to take means along the dimensions within a given cell(Matrix), but along the dimensions of Cell, NOT cell.

 Accepted Answer

Azzi Abdelmalek
Azzi Abdelmalek on 15 Feb 2013
Edited: Azzi Abdelmalek on 15 Feb 2013
Try this
Edit
%-----------Your array--------------------------------------------------
Y1={num2cell(rand(16,107)),num2cell(rand(16,47)),num2cell(rand(16,147))};
Y2={num2cell(rand(16,107)),num2cell(rand(16,47)),num2cell(rand(16,147))};
Y3={num2cell(rand(16,107)),num2cell(rand(16,47)),num2cell(rand(16,147))};
Y4={num2cell(rand(16,107)),num2cell(rand(16,47)),num2cell(rand(16,147))};
Ycell={Y1,Y2,Y3,Y4}
%----------------Your code------------------------------------------------
n=numel(Ycell);
m=numel(Ycell{1});
M=cell(n,m);
for p=1:m
for k=1:n
M{k,p}=cell2mat(Ycell{k}{p});
end
[ii,jj]=size(M{k,p});
a=cell2mat(M(1:n,p));
b=reshape(a',jj,ii,[]);
out{p}=nanmean(b,3)';
end
out

3 Comments

To check if it's correct:
nn=3;mm=11;
nanmean([Ycell{1}{nn}{mm} Ycell{2}{nn}{mm} Ycell{3}{nn}{mm} Ycell{4}{nn}{mm}])
out{nn}(mm)
CP
CP on 15 Feb 2013
Edited: CP on 15 Feb 2013
This seems to work, thanks! Though I'm not sure what the s=[] is for, so I removed it.
I've also deleted it.

Sign in to comment.

More Answers (2)

Azzi Abdelmalek
Azzi Abdelmalek on 14 Feb 2013
Edited: Azzi Abdelmalek on 14 Feb 2013
Yourcell={rand(16,107),rand(16,47),rand(16,147)}
out=cellfun(@(x) nanmean(x(:)),Yourcell,'un',0)
%or
Yourcell={rand(16,107),rand(16,47),rand(16,147)}
out=cellfun(@nanmean,Yourcell,'un',0)

7 Comments

CP
CP on 14 Feb 2013
This solution doesn't work. I get an error, because nanmean is trying to operate on a cell. For you it works because your overall cell contains 3 matrices, whereas mine contains 3 cells, and then THOSE cells contain the matrices. In other words tehre is an extra (and likely useless) cell container around each matrix.
If your data are
Yourcell={num2cell(rand(16,107)),num2cell(rand(16,47)),num2cell(rand(16,147))}
out=cellfun(@(x) nanmean(cell2mat(x(:))),Yourcell,'un',0)
CP
CP on 14 Feb 2013
Edited: CP on 14 Feb 2013
My data are as described:
Cell_1(cell_1(Matrix),cell_2(Matrix),cell_3(Matrix))
Cell_2(cell_1(Matrix),cell_2(Matrix),cell_3(Matrix))
Cell_3(cell_1(Matrix),cell_2(Matrix),cell_3(Matrix))
Cell_4(cell_1(Matrix),cell_2(Matrix),cell_3(Matrix))
I want to get 3 mean matrices, one of all cell_1(Matrix), one of all cell_2(Matrix), and one of all cell_3(Matrix), where the 3 mean matrices are of size cell_1(Matrix), cell_2(Matrix), and cell_3(Matrix). I do not want to take means along the dimensions within a given cell(Matrix), but along the dimensions of Cell, NOT cell.
Try this
Y1={num2cell(rand(16,107)),num2cell(rand(16,47)),num2cell(rand(16,147))}
Y2={num2cell(rand(16,107)),num2cell(rand(16,47)),num2cell(rand(16,147))}
Y3={num2cell(rand(16,107)),num2cell(rand(16,47)),num2cell(rand(16,147))}
Y4={num2cell(rand(16,107)),num2cell(rand(16,47)),num2cell(rand(16,147))}
Ycell={Y1,Y2,Y3,Y4}
out=cellfun(@(y) cellfun(@(x) nanmean(cell2mat(x(:))),y,'un',0),Ycell,'un',0)
CP
CP on 14 Feb 2013
Edited: CP on 14 Feb 2013
That also doesn't work. It returns 4 {1 x 3} cell arrays, where instead it should return 1 {1 x 3} cell array (or matrix).
Again, the mean we're trying to take is a mean of
(Cell_1(cell_1(Matrix))+Cell_2(cell_1(Matrix))+Cell_3(cell_1(Matrix))+Cell_4(cell_1(Matrix)))./4
and
(Cell_1(cell_2(Matrix))+Cell_2(cell_2(Matrix))+Cell_3(cell_2(Matrix))+Cell_4(cell_2(Matrix)))./4
and
(Cell_1(cell_3(Matrix))+Cell_2(cell_3(Matrix))+Cell_3(cell_3(Matrix))+Cell_4(cell_3(Matrix)))./4
Ok
out=cellfun(@(y) cellfun(@(x) nanmean(cell2mat(x(:))),y,'un',0),Ycell,'un',0)
res=nanmean(cell2mat(cellfun(@(x) cell2mat(x)',out,'un',0)),2)
CP
CP on 14 Feb 2013
It should return a 1 {1 x 3} cell array of 16x107, 16x47, and 16x147 means, not just 3 means but 3 arrays. As illustrated in my comment above, the equivalent of adding the 4 matrices, then dividing by 4. It should produce the same structure and values as what I typed above.
Thank you for all your help by the way, I appreciate it :)

Sign in to comment.

Sean de Wolski
Sean de Wolski on 14 Feb 2013
Edited: Sean de Wolski on 14 Feb 2013
I think you need two cellfuns with the inner-cellfun being part of the anonymous function for the first:
cellfun(@(c)cellfun(@(x)nanmean(x),c,'uni',false),your_cell,'uni',false)

1 Comment

CP
CP on 14 Feb 2013
Edited: CP on 14 Feb 2013
This solution takes means for each cell only within the cell itself, and not across all cells. For a cell size 4, it returns 4 cells, each of which contain 3 sub-cells with matrices that are 1x107, 1x47, and 1x147. Instead, as stated in the post I want to end up with just 3 matrices of size 16x107, 16x47, and 16x147, where for example the first matrix was generated by taking the first matrices in each of 4 cells (so taking 4 16x107 matrices) and taking a mean of those values across the cells (so for each mean value only 4 values go into it), and a single 16x107 matrix is returned such that value (1,1) in that mean matrix is a mean of the 4 values at (1,1) from each first matrix of the 4 cells, etc. God this is really confusing to describe, sorry :)

Sign in to comment.

Categories

Tags

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!