A compact way to sum the elements contained in two cell arrays (considering the case of empty cells as well)

조회 수: 3 (최근 30일)
Given two cell arrays a and b, as in the example here below, is there any compact way to:
  • sum the elements of the first cell array of a with the elements of the first cell array of b,
  • sum the elements of the second cell array of a with the elements of the second cell array of b,
  • sum the elements of the third cell array of a with the elements of the third cell array of b,
  • and so on.....?
Something like this for example ?
c{1} = a{1}+b{1}
c{2} = a{2}+b{2}
c{3} = a{3}+b{3}
...
Please see the following example:
% Input
>> a
a =
3×1 cell array
{[ 0 0 0 0 0 0 0 36 43 48 42 49 51 64 55 57 86 69 53 37 35 37 31 0]}
{[21 0 0 0 0 0 0 31 64 53 50 81 55 72 76 93 108 81 81 52 50 38 32 41]}
{[ 0 0 0 0 0 0 0 0 29 35 32 41 34 42 21 38 23 36 30 32 0 0 0 0]}
>> b
b =
3×1 cell array
{0×0 double }
{[548 296 154 116 148 220 370 773 1149 1014 1282 1182 1305 1303 1335 1463 1587 1465 1470 1114 1083 786 941 934]}
{[ 56 41 23 0 0 0 48 49 127 182 235 239 252 227 255 301 226 199 176 109 110 91 108 68]}
% Desired Output
>> c
c =
3×1 cell array
{[ 0 0 0 0 0 0 0 36 43 48 42 49 51 64 55 57 86 69 53 37 35 37 31 0]}
{[569 296 154 116 148 220 370 804 1213 1067 1332 1263 1360 1375 1411 1556 1695 1546 1551 1166 1133 824 973 975]}
{[ 56 41 23 0 0 0 48 49 156 217 267 280 286 269 276 339 249 235 206 141 110 91 108 68]}
>>

채택된 답변

Stephen23
Stephen23 2023년 2월 9일
편집: Stephen23 2023년 2월 9일
a = {[0,0,0,0,0,0,0,36,43,48,42,49,51,64,55,57,86,69,53,37,35,37,31,0];
[21,0,0,0,0,0,0,31,64,53,50,81,55,72,76,93,108,81,81,52,50,38,32,41];
[0,0,0,0,0,0,0,0,29,35,32,41,34,42,21,38,23,36,30,32,0,0,0,0]};
b = {[];
[548,296,154,116,148,220,370,773,1149,1014,1282,1182,1305,1303,1335,1463,1587,1465,1470,1114,1083,786,941,934];
[56,41,23,0,0,0,48,49,127,182,235,239,252,227,255,301,226,199,176,109,110,91,108,68]};
This works if either a or b contain empty matrices:
f = @(x,y)sum(cat(3,x,y),3);
c = cellfun(f,a,b,'uni',0)
c = 3×1 cell array
{[ 0 0 0 0 0 0 0 36 43 48 42 49 51 64 55 57 86 69 53 37 35 37 31 0]} {[569 296 154 116 148 220 370 804 1213 1067 1332 1263 1360 1375 1411 1556 1695 1546 1551 1166 1133 824 973 975]} {[ 56 41 23 0 0 0 48 49 156 217 267 280 286 269 276 339 249 235 206 141 110 91 108 68]}
It relies on this behavior of the CAT() function: "When concatenating an empty array to a nonempty array, cat omits the empty array in the output. For example, cat(2,[1 2],[]) returns the row vector [1 2]."
  댓글 수: 3
Paul
Paul 2023년 2월 9일
Excellent solution.
One case that could cause a problem would be if a and b both contained an empty matrix in the same element and those emptys are not compatible for concatentation:
f = @(x,y)sum(cat(3,x,y),3);
a={zeros(0,1)};
b={zeros(1,0)};
c = cellfun(f,a,b,'uni',0)
Error using cat
Dimensions of arrays being concatenated are not consistent.

Error in solution (line 1)
f = @(x,y)sum(cat(3,x,y),3);
So it depends on what the possibilites are for however those empty matrices showed up in a and b. Also, if the empties are of different dimension and compatible for concatenation, make sure to look at how this works and that it gives the result you want.
If the empty matrix in a or b will alwasy be 0 x 0, as in the example, then there should never be a problem, I don't believe.
Sim
Sim 2023년 2월 9일
Oh, sharp insight, I did not notice this aspect...! So, in case both a and b contained an empty matrix in the same element, and those empties were not compatible for concatenation, I would get that error... Well, at least, I would get an error that I could try to solve, and not just an unexpected odd value/outcome without any error, that I would not likely have noticed... :-)

댓글을 달려면 로그인하십시오.

추가 답변 (1개)

Paul
Paul 2023년 2월 9일
편집: Paul 2023년 2월 9일
Would be easier if the first element of b weren't empty. Logic would need to be modified a bit if there is a possiblity that a can contain empty arrays.
a = {[ 0 0 0 0 0 0 0 36 43 48 42 49 51 64 55 57 86 69 53 37 35 37 31 0];
[21 0 0 0 0 0 0 31 64 53 50 81 55 72 76 93 108 81 81 52 50 38 32 41];
[ 0 0 0 0 0 0 0 0 29 35 32 41 34 42 21 38 23 36 30 32 0 0 0 0]};
b = {[];
[548 296 154 116 148 220 370 773 1149 1014 1282 1182 1305 1303 1335 1463 1587 1465 1470 1114 1083 786 941 934] ;
[ 56 41 23 0 0 0 48 49 127 182 235 239 252 227 255 301 226 199 176 109 110 91 108 68]} ;
k = cellfun(@isempty,b);
c = cell(size(a));
c(k) = a(k);
c(~k)= cellfun(@(a,b) a+b,a(~k),b(~k),'Uni',0);
c
c = 3×1 cell array
{[ 0 0 0 0 0 0 0 36 43 48 42 49 51 64 55 57 86 69 53 37 35 37 31 0]} {[569 296 154 116 148 220 370 804 1213 1067 1332 1263 1360 1375 1411 1556 1695 1546 1551 1166 1133 824 973 975]} {[ 56 41 23 0 0 0 48 49 156 217 267 280 286 269 276 339 249 235 206 141 110 91 108 68]}
  댓글 수: 3
Paul
Paul 2023년 2월 9일
You're not wrong, that only checks if b is empty. Would also need to check for empty elements of I'd need to also check for empty cells in a and then deal with all combinations of empty/not-empty appropriately.

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 Logical에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by