Matlab Datenum函数很慢。我能做什么?

Matlab Datenum函数很慢。我能做什么?,matlab,octave,Matlab,Octave,我正在尝试将字符向量(200000行)转换为Matlab序列号。 格式为'01/07/2015 00:00:59' 这需要相当长的时间,在网上我只能找到在Matlab中解决这个问题的技巧。有什么办法可以改进吗?您可以使用datenum的输入类型 它比字符串解析快得多。每当我必须导入长日期/时间数据(几乎每天都要导入)时,我经常使用这个技巧 它包括发送一个mx6(或mx3)矩阵,其中包含表示[yy-mm-dd-HH-mm-SS]的值。矩阵的类型应为double 这意味着不让Matlab/Octav

我正在尝试将字符向量(200000行)转换为Matlab序列号。
格式为
'01/07/2015 00:00:59'

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

您可以使用
datenum
的输入类型

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

它包括发送一个
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的速度,但我确信它也会提高倍频程。至少在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]) ) ;
但是我对它进行了测试,改进非常有限,因此不值得失去可读性。

您可以将输入类型用于
datenum

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

它包括发送一个
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的速度,但我确信它也会提高倍频程。至少在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]) ) ;
但是我对它进行了测试,改进非常有限,因此不值得失去可读性。

您可以将输入类型用于
datenum

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

它包括发送一个
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的速度,但我确信它也会提高倍频程。至少在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]) ) ;
但是我对它进行了测试,改进非常有限,因此不值得失去可读性。

您可以将输入类型用于
datenum

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

它包括发送一个
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的速度,但我确信它也会提高倍频程。至少在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]) ) ;

但是我对它进行了测试,改进非常有限,因此不值得失去可读性。

您的输入可能是一个字符串单元格数组?如何调用datenum,是否传递格式?在线解决该问题的Matlab提示是什么?你确定他们不只是在八度工作吗?提示在哪里使用matlab中的.mex文件,这些文件在八度中不可用。我的输入是字符串数组,但我将其转换为字符矩阵。这有区别吗?@BallzofFury提示说,查看
datenum
的代码内部,提取特定字符串格式调用的位,然后使用该代码。在Matlab中,它调用的是一个mex函数,但无论调用什么倍频程,都应该更快。是否可以将断点添加到
datenum
?我们的想法是跳过所有的处理过程