Datenum功能很慢。我该怎么办?

时间:2015-07-31 13:00:54

标签: matlab octave

我试图将字符向量(200,000行)转换为Matlab序列号 格式为'01/07/2015 00:00:59'

这需要相当长的时间,在线我只能在Matlab中找到解决这个问题的技巧。我有什么想法可以改善这个吗?

1 个答案:

答案 0 :(得分:3)

您可以使用datenum的{​​{3}}类型的输入。

它比字符串解析快得多。每当我必须导入长日期/时间数据(几乎是每天)时,我经常使用这个技巧。

它包括发送mx6(或mx3)矩阵,其中包含代表[yy mm dd HH MM SS]的值。矩阵应为double类型。

这意味着不是让Matlab / Octave进行解析,而是用您喜欢的方式阅读字符串中的所有数字(textscanfscanfsscanf,...) ,然后您将号码发送到datenum而不是字符串。

在下面的例子中,我生成了一个日期字符串的长数组(86401x19)作为样本数据:

>> strDate(1:5,:)
ans =
31/07/2015 15:10:13
31/07/2015 15:10:14
31/07/2015 15:10:15
31/07/2015 15:10:16
31/07/2015 15:10:17

要比传统方式更快地将其转换为datenum,我使用:

strDate = [strDate repmat(' ',size(strDate,1),1)] ; %// add a whitespace at the end of each line
M = textscan( strDate.' , '%f/%f/%f %f:%f:%f'  ) ;  %'// read each value independently
M = cell2mat(M) ;                                   %// convert to matrix
M = M(:,[3 2 1 4 5 6]) ;                            %// reorder columns

dt = datenum(M ) ;                                  %// convert to serial date

这应该会在Matlab中加速,但我很确定它也应该改进Octave中的东西。至少在Matlab上量化一下,这是一个快速的基准:

function test_datenum

d0 = now ;
d = (d0:1/3600/24:d0+1).' ; %// 1 day worth of date (one per second)

strDate = datestr(d,'dd/mm/yyyy HH:MM:SS') ; %'// generate the string array

fprintf('Time with automatic date parsing: %f\n' , timeit(@(x) datenum_auto(strDate)) )
fprintf('Time with customized date parsing: %f\n', timeit(@(x) datenum_preparsed(strDate)) )


function dt = datenum_auto(strDate)
    dt = datenum(strDate,'dd/mm/yyyy HH:MM:SS') ;       %// let Matlab/Octave do the parsing


function dt = datenum_preparsed(strDate)
    strDate = [strDate repmat(' ',size(strDate,1),1)] ; %// add a whitespace at the end of each line
    M = textscan( strDate.' , '%f/%f/%f %f:%f:%f'  ) ;  %'// read each value independently
    M = cell2mat(M) ;                                   %// convert to matrix

    M = M(:,[3 2 1 4 5 6]) ;                            %// reorder columns

    dt = datenum(M ) ;                                  %// convert to serial date

在我的机器上,它产生:

>> test_datenum
Time with automatic date parsing: 0.614698
Time with customized date parsing: 0.073633

当然你也可以用几行来压缩代码:

M = cell2mat(textscan([strDate repmat(' ',size(strDate,1),1)].','%f/%f/%f %f:%f:%f'))) ;
dt = datenum( M(:,[3 2 1 4 5 6]) ) ;

但是我对它进行了测试,并且改进是如此微不足道,以至于失去可读性并不值得。