Mean of a cell array with different cell sizes?

Mean of a cell array with different cell sizes?
% This works:
a = {[1 3 4 5];[7 7 8 2];[5 4 1 9]}
a = 3×1 cell array
{[1 3 4 5]} {[7 7 8 2]} {[5 4 1 9]}
mean(cell2mat(a),2)
ans = 3×1
3.2500 6.0000 4.7500
% but this does not work:
a = {[1 3 4 5];[7 7 8 2];[5 4 1]}
a = 3×1 cell array
{[1 3 4 5]} {[7 7 8 2]} {[ 5 4 1]}
mean(cell2mat(a),2)
Error using cat
Dimensions of arrays being concatenated are not consistent.

Error in cell2mat (line 83)
m{n} = cat(1,c{:,n});

 Accepted Answer

If the data in the cell array is compatible for concatenation, concatenate them and use mean for the specific dimension -
a = {[1 3 4 5];[7 7 8 2];[5 4 1 9]}
a = 3×1 cell array
{[1 3 4 5]} {[7 7 8 2]} {[5 4 1 9]}
b = cat(1,a{:})
b = 3×4
1 3 4 5 7 7 8 2 5 4 1 9
m = mean(b, 2)
m = 3×1
3.2500 6.0000 4.7500
If the data in the cell array is not compatible for concatenation, the best approach would be to pre-allocate the output and use a for loop. You could use cellfun() but that is just a for loop in disguise.

6 Comments

Gosh, you were very fast to reply and meanwhile I modified my question a bit.. :-)
Btw, Thanks a lot, very kind!
...but what if the cells sizes are different, like in the following example?
a = {[1 3 4 5];[7 7 8 2];[5 4 1]}
a = 3×1 cell array
{[1 3 4 5]} {[7 7 8 2]} {[ 5 4 1]}
mean(cell2mat(a),2)
Error using cat
Dimensions of arrays being concatenated are not consistent.

Error in cell2mat (line 83)
m{n} = cat(1,c{:,n});
As I mentioned in my answer - pre-allocate the output and use a for loop.
a = {[1 3 4 5];[7 7 8 2];[5 4 1]}
a = 3×1 cell array
{[1 3 4 5]} {[7 7 8 2]} {[ 5 4 1]}
n = numel(a);
c = zeros(n,1);
for k=1:n
c(k) = mean(a{k});
end
c
c = 3×1
3.2500 6.0000 3.3333
Got it, many thanks!
(also with cellfun as you said)
a = {[1 3 4 5];[7 7 8 2];[5 4 1]}
a = 3×1 cell array
{[1 3 4 5]} {[7 7 8 2]} {[ 5 4 1]}
cellfun(@mean,a,'uni',false)
ans = 3×1 cell array
{[3.2500]} {[ 6]} {[3.3333]}
Speed comparison -
%Generate random data
vec = randi([25 50], 1, 50000);
s = sum(vec)
s = 1873054
arr = randi([1e3 1e4], 1, s);
%Data in the form of cell array
data = mat2cell(arr, 1, vec);
f1 = @(x) funfor(x);
f2 = @(x) funcell(x);
F1 = @() f1(data);
F2 = @() f2(data);
%First check whether output is equal or not
isequal(F1(), F2())
ans = logical
1
%Timings
fprintf('Time taken by the for loop = %f seconds', timeit(F1))
Time taken by the for loop = 0.025663 seconds
fprintf('Time taken by cellfun = %f seconds', timeit(F2))
Time taken by cellfun = 0.103503 seconds
function c = funfor(x)
n = numel(x);
c = zeros(1,n);
for k=1:n
c(k) = mean(x{k});
end
end
function c = funcell(x)
c = cellfun(@mean, x);
end
@Sim, Using the name-argument pair will give the output as a cell array.
a = {[1 3 4 5];[7 7 8 2];[5 4 1]}
a = 3×1 cell array
{[1 3 4 5]} {[7 7 8 2]} {[ 5 4 1]}
cellfun(@mean,a)
ans = 3×1
3.2500 6.0000 3.3333
ah ok, even better! Super thank you!

Sign in to comment.

More Answers (0)

Categories

Find more on Loops and Conditional Statements in Help Center and File Exchange

Asked:

Sim
on 28 Nov 2023

Commented:

Sim
on 28 Nov 2023

Community Treasure Hunt

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

Start Hunting!