您可以对datenum 使用datenum(datevector) 类型的输入。
它比字符串解析要快得多。每当我必须导入长日期/时间数据(几乎每天)时,我经常使用这个技巧。
它包括发送一个mx6(或mx3)矩阵,其中包含代表[yy mm dd HH MM SS]的值。矩阵的类型应为double。
这意味着不是让 Matlab/Octave 进行解析,而是用自己喜欢的方式(textscan、fscanf、sscanf、...)读取字符串中的所有数字,然后将数字发送到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]) ) ;
但我对其进行了测试,但改进是如此微不足道,以至于失去可读性并不值得。