MATLAB Answers

0

Preallocating memory for a cell array of unknown size & removing the empty rows in cells array

Asked by sangeetha r on 8 Feb 2017
Latest activity Commented on by Guillaume
on 9 Feb 2017
I have set of data in a cell array whose size is previously unknown. Size of cell array is probably in the range of 3000*3 to 5000*3. I thought of allocating 6000*3 size to the variable initially, then after execution removing the empty rows from the cell array. For Example:
A = cell(6000, 3)
after execution,
A (6000*3 cell array)=
'y4' 'HT' 9
'y2' 'VN' 1
'y5' 'TE' 10
'y3' 'NH' 10
'y6' 'EY' 9
'y7' 'YY' 78
[] [] []
[] [] []
then removing the empty rows. Whether my approach is correct? How do i remove the empty rows from the cell array so that variable A becomes
A (6*3 cell array)=
'y4' 'HT' 9
'y2' 'VN' 1
'y5' 'TE' 10
'y3' 'NH' 10
'y6' 'EY' 9
'y7' 'YY' 78

  0 Comments

Sign in to comment.

3 Answers

Answer by Thibaut Jacqmin on 8 Feb 2017
Edited by Thibaut Jacqmin on 8 Feb 2017

You can use the following cell function :
A(~cellfun('isempty',A))'

  2 Comments

but this will give the m*1 cell array as output. I require the output in the same shape as 'A' i.e. m*3 cell array
Maybe I did not understand your problem since according to me it works.
A = cell(6000, 3);
A{1, 1} = 'y4';
A{1, 2} = 'HT';
A{1, 3} = 9;
(Here I filled only the first line.)
Then
A(~cellfun('isempty',A))'
gives you a 1x3 cell array

Sign in to comment.


Answer by Guillaume
on 8 Feb 2017
Edited by Guillaume
on 9 Feb 2017

A(~all(cellfun(@isempty, A), 2), :)

  4 Comments

Show 1 older comment
As usual I mention, that cellfun('isempty') is remarkably faster than cellfun(@isempty). Sorry for repeating myself, but I cannot resist to point to this gem.
Yes, but the string form was deprecated (in R2012 iirc) and is sort of hidden (under backwards compatibility) in the documentation.
Hopefully, at some point (been waiting a long time ...) matlab optimiser will become good enough that function handle call will have almost no penalty and the string form won't be necessary.
In general, I don't worry about the performance implication and prefer a consistent style, always using function handles.

Sign in to comment.


Answer by Philip Borghesani on 8 Feb 2017
Edited by Philip Borghesani on 8 Feb 2017

Your question bring a few points to mind before even answering it.
  1. Preallocating cell arrays and structures is not as helpful or necessary as it is for numeric matrices. This is because when a cell array is resized only the pointers/headers for the cell data needs to be moved from the old location to the new one.
  2. If possible all MATLAB variables should be grown or shrunk in only the last dimension. Your code will be more efficient if your cell array is transposed, again this is more important for numeric data then cells or structures.
%if you transpose the data and asize is the final size of your data then to shrink
% your data to the final size:
shrunkA=A(:,1:asize);
%or
A(:,asize+1:end)=[];
%optionally transpose the results to be compatible with other code.
Both methods should have about the same performance and will work on untransposed arrays but will be slower.

  2 Comments

(Updated I had a bug that did not effect the conclusion)
I said not as important take a look at these times:
>> prealloc
Baseline is 0.228884 seconds
Growing array takes 0.773912 seconds
With prealloc takes 0.257996 seconds
Growing cell array takes 0.237646 seconds
Preallocated cell array takes 0.228955 seconds
In addition the array growth timing experiments given in the two thread are no longer representative of real world performance because of the Array growth optimization added in R2011a.
prealloc.m:
rows=100;
cols=100;
num=8000;
%Baseline
clear a;
tic
a=ones(cols,rows,num);
fprintf('Baseline is %g seconds\n',toc);
clear a
%grow a
tic
for n=1:num
a(:,:,n)=ones(cols,rows);
end
fprintf('Growing array takes %g seconds\n',toc);
clear a
%grow a
tic
a=zeros(cols,rows,num);
for n=1:num
a(:,:,n)=ones(cols,rows);
end
fprintf('With prealloc takes %g seconds\n',toc);
%%now do with cells
clear a
%grow a
tic
for n=1:num
a{n}=ones(cols,rows);
end
fprintf('Growing cell array takes %g seconds\n',toc);
clear a
%prealloc a
a=cell(num,1);
tic
for n=1:num
a{n}=ones(cols,rows);
end
fprintf('Preallocated cell array takes %g seconds\n',toc);

Sign in to comment.