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.

 Réponse acceptée

Azzi Abdelmalek
Azzi Abdelmalek le 15 Fév 2013
Modifié(e) : Azzi Abdelmalek le 15 Fév 2013

0 votes

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 commentaires

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 le 15 Fév 2013
Modifié(e) : CP le 15 Fév 2013
This seems to work, thanks! Though I'm not sure what the s=[] is for, so I removed it.
Azzi Abdelmalek
Azzi Abdelmalek le 15 Fév 2013
I've also deleted it.

Connectez-vous pour commenter.

Plus de réponses (2)

Azzi Abdelmalek
Azzi Abdelmalek le 14 Fév 2013
Modifié(e) : Azzi Abdelmalek le 14 Fév 2013

0 votes

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 commentaires

CP
CP le 14 Fév 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.
Azzi Abdelmalek
Azzi Abdelmalek le 14 Fév 2013
Modifié(e) : Azzi Abdelmalek le 14 Fév 2013
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 le 14 Fév 2013
Modifié(e) : CP le 14 Fév 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 le 14 Fév 2013
Modifié(e) : CP le 14 Fév 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
Azzi Abdelmalek
Azzi Abdelmalek le 14 Fév 2013
Modifié(e) : Azzi Abdelmalek le 14 Fév 2013
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 le 14 Fév 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 :)

Connectez-vous pour commenter.

Sean de Wolski
Sean de Wolski le 14 Fév 2013
Modifié(e) : Sean de Wolski le 14 Fév 2013

0 votes

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 commentaire

CP
CP le 14 Fév 2013
Modifié(e) : CP le 14 Fév 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 :)

Connectez-vous pour commenter.

Catégories

Tags

Community Treasure Hunt

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

Start Hunting!

Translated by