MATLAB Answers

Optimizing a 'for' loop

3 views (last 30 days)
djr
djr on 10 Feb 2015
Commented: Titus Edelhofer on 10 Feb 2015
Hello,
I have a cell containing two cell columns. Column 1 is date and Column 2 is hour. I want to merge them together and transfrom date/time to the Matlab format. I am using a 'for' loop to do this, because I wasn't able to do it using 'cellfun'. This is the code:
for i=1:385521
PT{1}{i,1} = datenum(strcat(PT{1,1}{i,1},PT{1,2}{i,1}),'dd.mm.yyyyHH');
end
This works, but it takes about 6 minuts to do this operation. Could you give me some suggestions on how to optimize this operation. Even better if it is not in a loop.
Thanks, DjR

  1 Comment

djr
djr on 10 Feb 2015
This is the sample of the input file (first few lines) and the whole for loop:
fid = fopen('test.txt');
PT = textscan(fid, '%s %s %f %f','Delimiter',',', 'HeaderLines',1);
fclose(fid);
clear ans fid
% Organize data (remove 00:00:00) and convert date to Matlab format
PT{1} = cellfun(@(x) strrep(x, ' 00:00:00',''), PT{1},'UniformOutput',false);
PerRow = cell2mat(strfind(PT{:,1},'.'));
for i=1:length(PT{:,1})
% add two zeros if format is m.d.yyyy
if PerRow(i,1) == 2 && PerRow(i,2) == 4
PT{1}{i,1} = ['0', PT{1,1}{i,1}(1:2), '0', PT{1}{i,1}(3:end)];
% Add one zero if format is d.mm.yyyy
elseif PerRow(i,1) == 2 && PerRow(i,2) ~=4
PT{1}{i,1} = ['0', PT{1}{i,1}];
% Add one zero if format is dd.m.yyyy
elseif PerRow(i,2) == 5
PT{1}{i,1} = [PT{1}{i,1}(1:3), '0', PT{1}{i,1}(4:end)];
end
% Add zero if format is H
if size(PT{1,2}{i},2) == 1
PT{1,2}{i}=['0', PT{1,2}{i}];
end
% Combain columns and transform date/time to Matlab format
PT{1}{i,1} = datenum(strcat(PT{1,1}{i,1},PT{1,2}{i,1}),'dd.mm.yyyyHH');
end
clear i PerRow
The loop without the problematic line takes only about 20 sec on my Linux computer.

Sign in to comment.

Accepted Answer

Titus Edelhofer
Titus Edelhofer on 10 Feb 2015
Hi,
you should do the strcat out of the loop, something like
PT12 = strcat(PT{1,1}(:,1), PT{1,2}(:,1));
and then you don't need the loop on datenum
PTnum = datenum(PT12, 'dd.mm.yyyyHH');
Titus

  3 Comments

Titus Edelhofer
Titus Edelhofer on 10 Feb 2015
This works fine with your example: take the problematic line out of the loop and "my" two lines after the loop ...
djr
djr on 10 Feb 2015
Thanks a lot. It is much more efficient. It takes like 30 seconds to finish. It took about 6 minutes when the line was in the loop.
Titus Edelhofer
Titus Edelhofer on 10 Feb 2015
Your welcome. Usually MATLAB is not that bad on loops anymore. But datenum is using a MEX file in the back ground, which has some overhead when called in a (large) loop.

Sign in to comment.

More Answers (0)

Community Treasure Hunt

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

Start Hunting!

Translated by