Concatenate subcells through one dimension of a cell array without using loops in MATLAB -
Concatenate subcells through one dimension of a cell array without using loops in MATLAB -
i have cell array. each cell contains vector of variable length. example:
example_cell_array=cellfun(@(x)x.*rand([length(x),1]),cellfun(@(x)ones(x,1), num2cell(ceil(10.*rand([7,4]))), 'uniformoutput', false), 'uniformoutput', false) i need concatenate contents of cells downwards through 1 dimension perform operation on each concatenated vector generating scalar each column in cell array (like sum() illustration - actual operation complex, time consuming, , not naturally vectorisable - diffent length vecotrs).
i can loops (for concatenated vector sum example) follows:
[m n]=size(example_cell_array); result=zeros(1,n); cat_cell_array=cell(1,n); n=1:n cat_cell_array{n}=[]; m=1:m cat_cell_array{n}=[cat_cell_array{n};example_cell_array{m,n}]; end end result=cell2mat(cellfun(@(x)sum(x), cat_cell_array, 'uniformoutput', false)) unfortunately way slow. (my cell array 1mx5 vectors in each cell ranging in length 100-200)
is there simple way produce concatenated cell array vectors contained in cells have been concatenated downwards 1 dimension?
something like:
dim=1; cat_cell_array=(?concatcells?(dim,example_cell_array); edit: since many people have been testing solutions: fyi, function i'm applying each concatenated vector circ_kappa(x) available circular statistics toolbox
some approaches might suggest unpack numeric info example_cell_array using {..} , after concatenation pack bigger sized cells form cat_cell_array. then, 1 time again need unpack numeric info concatenated cell array perform operation on each cell.
now, in view, multiple unpacking , packing approaches won't efficient ones if example_cell_array isn't 1 of intended outputs. so, considering these, allow me suggest 2 approaches here.
the first 1 for-loop code -
data1 = vertcat(example_cell_array{:}); %// extract numeric info 1 time starts = [1 sum(cellfun('length',example_cell_array),1)]; %// intervals lengths idx = cumsum(starts); %// indices work on intervals basis result = zeros(1,size(example_cell_array,2)); %// replace "result(size(example_cell_array,2))=0;" performance k1 = 1:numel(idx)-1 result(k1) = sum(data1(idx(k1):idx(k1+1)-1)); end so, need edit sum actual operation.
if example_cell_array has lot of columns, sec suggestion almost vectorized approach, though doesn't perform badly either little number of columns. code uses cellfun @ first line lengths each cell in concatenated version. cellfun wrapper loop code, not expensive in terms of runtime , that's why categorized approach almost vectorized one.
the code -
lens = sum(cellfun('length',example_cell_array),1); %// intervals lengths maxlens = max(lens); numlens = numel(lens); array1(maxlens,numlens)=0; array1(bsxfun(@ge,lens,[1:maxlens]')) = vertcat(example_cell_array{:}); %//' result = sum(array1,1); the thing need now, create operation run on column basis array1 using mask created bsxfun implementation. thus, if array1 m x 5 sized array, need select valid elements each column using mask , operation on elements. allow me know if need more info on masking issue.
hope 1 of these approaches work you!
quick tests: using 250000x5 sized example_cell_array, quick tests show both these approaches sum operation perform , give 400x speedup on code in question @ end.
arrays matlab vectorization cells cell-array
Comments
Post a Comment