Reputation: 41
I am trying to add vertically the lists of a database like DB (see below) contained in a cell.
DB={ {[11 12]} {[13 14]} {[15 16]} {[17 18]} {[19 20]};
{[21 22]} {[23 24]} {[25 26]} {[27 28]} {[29 30]};
{[31 32]} {[33 34]} {[35 36]} {[37 38]} {[39 40]}}
I would like to get:
[33 36] [69 72] [75 78] [81 44] [ 87 90 ]
I tried with a 'for' loop (see below) ... but taking too much time.
How could I do this with the minimum of 'for' loops or even better, without any loop?
Thank you very much for your attention.
sum=[ ]
for j=1:5
sumi=0
for i=1:3
sumi=sumi+ c2{i,j}{1}
end
sum=[sum sumi]
end
Upvotes: 2
Views: 65
Reputation: 112749
Based on your code, you can achieve the same result with
result = sum(cell2mat(cellfun(@(x) x, DB)), 1);
or better (thanks to @Wolfie)
result = sum(cell2mat(reshape([DB{:}], size(DB, 1), [])), 1);
This converts your cell array of cell arrays into a numerical 2D array, and then sums along the vertical dimension. However, this is not likely to be much faster than your current code.
The issue with your approach is not the code, but the data type. If possible, you should define your DB
variable directly as a numerical 2D array. That way the code would be simpler and faster: result = sum(DB, 1);
. Normally, cell arrays in Matlab are only used if the contents are not homogenous in size or in type.
Upvotes: 5
Reputation: 30146
One slightly faster approach is to reduce to a single loop, and pre-allocate the output:
n = 2;
s = NaN( 1, n*size(DB,2) );
for ii = 1:size(DB,2)
col = vertcat(DB{:,ii});
s(n*(ii-1)+1:n*ii) = sum( vertcat(col{:}) );
end
Note that n
here is the number of elements within each cell, which in your example was 2
.
Upvotes: 3
Reputation: 102529
Maybe you can try
table2cell(varfun(@(x) sum(cell2mat(x),1),cell2table(DB)))
and you will obtain the result presented like
1×5 cell array
{[63 66]} {[69 72]} {[75 78]} {[81 84]} {[87 90]}
Upvotes: 2