Begginer
Begginer

Reputation: 31

compute the means of a 3-dimensional cell array in matlab

I have a cell array C of size <20x1x19>, each one the 19 elements contains a set of 20 matrices of size (80x90), How can I want to compute the mean of each 20 matrix and store the result in a matrix M so that in the end I will have a Matrix of size 80x90x19 containing the means of the cell array matrices.

for example:

M(:,:,1) will have the mean of elements in C(:,:,1);

M(:,:,2) will have the mean of elements in C(:,:,2)

and so on.

Upvotes: 3

Views: 1467

Answers (2)

Jonas
Jonas

Reputation: 74940

A little bit of array manipulation allows you to forego the loop. You can change dimensions on your cell array so that cell2mat results in a 80-by-90-by-19-by-20 array, after which all you need to do is take the average along dimension #4:

%# C is a 20x1x19 cell array containing 80x90 numeric arrays

%# turn C into 1x1x19x20, swapping the first and fourth dimension
C = permute(C,[4 2 3 1]);

%# turn C into a numeric array of size 80-by-90-by-19-by-20
M = cell2mat(C);

%# average the 20 "slices" to get a 80-by-90-by-19 array
M = mean(M,4);

Upvotes: 4

angainor
angainor

Reputation: 11810

Assuming I understood you correctly, you can do what you want in the following way (the comments explain what I do step by step):

% allocate space for the output
R = zeros(80, 90, 19);

% iterate over all 19 sets
for i=1:19
    % extract ith set of 20 matrices to a separate cell
    icell = {C{:,1,i}};

    % concatenate all 20 matrices and reshape the result
    % so that one matrix is kept in one column of A 
    % as a vector of size 80*90
    A = reshape([icell{:}], 80*90, 20);

    % sum all 20 matrices and calculate the mean
    % the result is a vector of size 80*90
    A = sum(A, 2)/20;

    % reshape A into a matrix of size 80*90 
    % and save to the result matrix
    R(:,:,i) = reshape(A, 80, 90);    
end

You could skip the extraction to icell and concatenate the ith set of 20 matrices directly

A = reshape([C{:,1,i}], 80*90, 20);

I only did it here for some clarity.

The above steps can be more briefly (but definitely much more cryptically!) expressed by the following arrayfun call:

F = @(i)(reshape(sum(reshape([C{:,1,i}], 80*90, 20), 2)/20, 80, 90));
R = arrayfun(F, 1:19, 'uniform', false);
R = reshape([R2{:}], 80, 90, 19);

The anonymous function F does essentially one iteration of the loop. It is called 19 times by arrayfun, once for every set of matrices. I would suggest you stick with the loop.

Upvotes: 2

Related Questions