How to calculate max,min,average values from a cell array?

Hi, I have a cell array of size 1x316 with each cell of different sizes.All values in the cells are double numeric type.I want to find max, min , average values from each cell and save in a different cell arrays of sizes 1x316. This is my code for now:
I have stored cell array in struct s2.This cell array is of sie 1x316.I am trying to return max,min and avg values from a single for loop and saving outputs in 3 different cell arrays.Please help me out on this.
s2 = load('pause_durations_rome.mat');
max_pause_time =cell(size(s2.pause_duration));
min_pause_time = cell(size(s2.pause_duration));
average_pause_time = cell(size(s2.pause_duration));
for iter = 1:length(s2.pause_duration)
a=cell2mat(s2.pause_duration,);
max_pause_time{iter} = max(a(:));
min_pause_time{iter} = min(a(:));
average_pause_time{iter} = mean(a(:));
end

Answers (1)

Adam
Adam on 17 Mar 2016
Edited: Adam on 17 Mar 2016
min_pause_time = cellfun( @min, s2.pause_duration);
max_pause_time = cellfun( @max, s2.pause_duration );
average_pause_time = cellfun( @mean, s2.pause_duration );

13 Comments

Hi Adam,
sorry it's not working.Error showing- ''Error using cellfun Input #2 expected to be a cell array, was struct instead.''
Edited my answer so it should work now. That is the kind of correction it is useful for you to be able to easily make yourself though.
I just scanned your question, saw you were talking about a cell array and though that was s2 rather than that the cell array was in a structure, but is s2.pause_duration is your cell array then my amended answer should work.
I understand but i tried this way too but still it's not working.
''Error using cellfun Undefined function 'min' for input arguments of type 'cell'.''
Do you have a cell array inside a cell array? cellfun should act on the elements of a cell array. These elements, when presented to the min function will be whatever is inside each cell rather than the cell itself, so unless you have cell arrays inside cell arrays this should not be a problem.
If you do have a cell array inside a cell array is this really necessary? You should always use numeric arrays where possible.
Yes Adam, there are cell arrays inside cell arrays.Sorry i forgot to clarify this before.
The overall format from top to down looks like this:
1x316 cell array -> cell arrays of different sizes->double numeric values
So
min_pause_time = cellfun( @min, [s2.pause_duration{:}]);
max_pause_time = cellfun( @max, [s2.pause_duration{:}] );
average_pause_time = cellfun( @mean, [s2.pause_duration{:}] );
or use cell2num possibly. Anything that just turns your cell arrays into numeric arrays which they should probably be in the first place.
I appreciate your help Adam.But its still not working as i planned.I wanted to find mean, max, min value of each cell array and store them in separate cell arrays as output.I will elaborate more:
format of my data : 1x316 cell array->multi dimensional cell arrays->numeric values in each cells
steps to be taken:
find mean of each cell arrays and store as a new array- mean_cell_array
second find max value of each cell arrays and store as max_cell_array
finally find min value of each cell arrays and store as min_cell_array
So, finally, we should have 3 cell arrays of max, min and mean values from above entire cell arrays.
It will be easy for me to understand if you could provide answer in full program format.
Thanks for your time and effort once again.
"find mean of each cell arrays" you cannot calculate the mean of a cell array, only of numeric arrays. Ditto max and min.
You should also consider simplifying your data organization, as then your task would be much easier. If you want us to help you then please show us the exact organization of your data, something like this:
C = {X,Y...Z} % size 3x5
% where:
X = {M,N,..} % size 1x2
% where:
M = [100x2 double]
Hi Stephen, i have stored cell array in s2 which is a 1x1 struct with one field ->pause_duration of size 1x316. Clearly, there are 316 cell arrays of different sizes, like 1xa, 1xb, 1xc. all stored in a struct called s2 with variable name pause_duration. I need to calculate mean,max and min values among each of those 316 cell arrays and save in 3 different cell arrays as output say max_pause_duration(1x316), min_pause_duration(1x316) and mean_pause_duration(1x316). The cellfun function works very slow as its a big data.
format of s2.pause_duration is
1x8115 cell : data sample 0.0067 0.00408 0.000149 ....
1x4790 cell
1x6675 cell
1x4981 cell
1x7781 cell
1x5893 cell
1x7255 cell
1x802 cell
..........
..........
1x5242 cell
1x4469 cell
1x4108 cell
1x3404 cell
1x1724 cell
1x699 cell
1x548 cell
You should probably use a non-scalar structure to hold this data. Then your task would be trivial to achieve. Because this "cell array in s2 which is a 1x1 struct with one field ->pause_duration of size 1x316" sounds like it would be much better organized as a 1x316 structure.
In fact why do you need a structure at all if there is only one field?
Why are your numeric data stored in cell arrays?: "316 cell arrays of different sizes". This just makes your data processing much more complicated. Numeric data should be stored in numeric arrays.
If you really need a structure then use a non-scalar one, like this:
>> S(1).field = [0,1,2];
>> S(2).field = [3,4,5,6];
>> S(3).field = [7,8,9];
because then accessing the data is really simple:
>> C = {S.field};
>> cellfun(@min,C)
ans =
0 3 7
>> cellfun(@max,C)
ans =
2 6 9
>> cellfun(@mean,C)
ans =
1 4.5 8
You see: good data planning makes code neater, faster, and more robust.
All those data are extracted from 316 users so i need to process them individually and save in different cell arrays.I may need further processing in future so i can't change the format of data here.That's why i am facing complexity.
A non-scalar structure makes this trivial to implement:
S(1).user = 'anna';
S(2).user = 'bob';
S(3).user = 'chen';
...
S(1).data = [0,1,2];
S(2).data = [3,4,5,6];
S(3).data = [7,87,9];
You can add as many users as you need, and any fields that you want. And then accessing the data is very simple:
>> users = {S.user}
users =
'anna' 'bob' 'chen'
>> S(strcmp(users,'bob')).data
ans =
3 4 5 6
You are writing the code and extracting the data, so if you want to make your own life easier then simplify your data organization.
Thanks Stephen, now i got the picture.

Sign in to comment.

Categories

Asked:

on 17 Mar 2016

Commented:

on 21 Mar 2016

Community Treasure Hunt

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

Start Hunting!