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

22 ビュー (過去 30 日間)
sangeetha r
sangeetha r 2017 年 2 月 8 日
コメント済み: Guillaume 2017 年 2 月 9 日
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

回答 (3 件)

Thibaut Jacqmin
Thibaut Jacqmin 2017 年 2 月 8 日
編集済み: Thibaut Jacqmin 2017 年 2 月 8 日
You can use the following cell function :
A(~cellfun('isempty',A))'
  2 件のコメント
sangeetha r
sangeetha r 2017 年 2 月 8 日
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
Thibaut Jacqmin
Thibaut Jacqmin 2017 年 2 月 8 日
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

サインインしてコメントする。


Guillaume
Guillaume 2017 年 2 月 8 日
編集済み: Guillaume 2017 年 2 月 9 日
A(~all(cellfun(@isempty, A), 2), :)
  4 件のコメント
Jan
Jan 2017 年 2 月 9 日
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.
Guillaume
Guillaume 2017 年 2 月 9 日
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.

サインインしてコメントする。


Philip Borghesani
Philip Borghesani 2017 年 2 月 8 日
編集済み: Philip Borghesani 2017 年 2 月 8 日
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 件のコメント
Stephen23
Stephen23 2017 年 2 月 8 日
編集済み: Stephen23 2017 年 2 月 8 日
1. Adding new cells (i.e. pointers) onto an cell array is as inefficient as adding new elements onto a numeric array. Ditto for structures. Thus:
Philip Borghesani
Philip Borghesani 2017 年 2 月 8 日
編集済み: Philip Borghesani 2017 年 2 月 8 日
(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);

サインインしてコメントする。

カテゴリ

Help Center および File ExchangeMatrices and Arrays についてさらに検索

製品

Community Treasure Hunt

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

Start Hunting!

Translated by