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

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!