collapse across dimensions of a matrix

I have a multidimensional matrix 19 x 64 x 5 x 21 which corresponds to 19 participants x 64 channels x 5 timepoints x 21 data values.
I want to collapse the last two dimensions of the matrix so that I end up with the mean of the (5 x 21) data values, per participant, per channel (i.e. a 19 x 64 (x1) matrix)
I've tried using mean, tried using reshape etc but I am really struggling with the scale of the data and picturing how the the four dimensions fit together. As such I can't confidently manipulate the data across the four dimensions so any guidance would be appreciated.

 Accepted Answer

If you're using release R2018b or later, several data analysis functions (including mean) can accept a vector of dimensions over which to operate. See the Release Notes for a list of which functions can accept a vector of dimensions.

4 Comments

+1
mean(rand(19 , 64 , 5 , 21),[3 4]) % last two dimensions
this would be perfect but doesn't appear to be implemented yet for nanmean?
Using madhan ravi's example, slightly modified:
First generate a sample array.
R = rand(19, 64, 5, 21);
Next add in a couple NaN values at random locations. I made a copy of R with which to work so you can compare them later.
nanloc = randperm(numel(R), 30);
R2 = R;
R2(nanloc) = NaN;
Finally take the mean ignoring NaN values.
result = mean(R2, [3 4], 'omitnan');
Thank you so much - works perfectly and so very simple :) !!

Sign in to comment.

More Answers (4)

Give this a try:
% Generate random matrix
A = randi(10,[19 64]);
B = cat(3,A,A,A,A);
C = cat(4,B,B);
% Get indices and set counter
[idx1 idx2 idx3 idx4] = size(C);
counter = 1;
% Build cell array of all the matrices
for ii = 1:idx4
for jj = 1:idx3
out{counter} = C(:,:,idx3,idx4);
counter = counter + 1;
end
end
% Calculate the mean
dim = ndims(out{1});
M = cat(dim+1,out{:});
meanMatrix = mean(M,dim+1);

1 Comment

MsPop
MsPop on 21 Dec 2018
Edited: MsPop on 22 Dec 2018
Many thanks, that appears to have worked!
Update: I'm manually calculating the mean value for one participant at one channel to double check that this is working (i.e. the mean across the 105 values) but it unfortunately doesn't tally. I think that it goes wrong in the build of the out variable, because the resulting 19x64 array is repeated across every one of the 105 cells. I reran the original code to check but it is hard to check there because of the way the matrices have been built. But I think that the following replicates the problem:
%% Generate random matrix
A = randi(10,[19 64]);
B = randi(10,[19 64]);
BB = cat(3,A,B,A,B);
CC = cat(3,B,A,B,A);
C = cat(4,BB,CC);
% Get indices and set counter
[idx1 idx2 idx3 idx4] = size(C);
counter = 1;
% Build cell array of all the matrices
for ii = 1:idx4
for jj = 1:idx3
out{counter} = C(:,:,idx3,idx4);
counter = counter + 1;
end
end
% Calculate the mean
dim = ndims(out{1});
M = cat(dim+1,out{:});
meanMatrix = mean(M,dim+1);

Sign in to comment.

Using sepblockfun (Download),
sepblockfun(yourArray, [1,1,inf,inf], 'mean')

Products

Release

R2018b

Asked:

on 21 Dec 2018

Commented:

on 22 Dec 2018

Community Treasure Hunt

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

Start Hunting!