比MATLAB中的datenum更快的功能

时间:2011-04-28 12:29:22

标签: matlab date performance

有没有人知道将日期字符串(2010-12-12 12:21:12.123)转换为数字的更快方法?

4 个答案:

答案 0 :(得分:18)

通常需要对内置的Matlab函数进行分析,并仅提取感兴趣的内部功能。

在您的特定情况下,

dtstr2dtnummx({'2010-12-12 12:21:12.123'},'yyyy-MM-dd HH:mm:ss')

比以下快3倍(占30%的时间):

datenum({'2010-12-12 12:21:12.123'},'yyyy-mm-dd HH:MM:SS')

其中dtstr2dtnummx是我的Windows机器上的内部函数(C:\ Program Files \ Matlab \ R2011a \ toolbox \ matlab \ timefun \ private \ dtstr2dtnummx.mexw32)。

要访问此内部函数,只需使用addpath函数将其文件夹添加到Matlab路径,或将dtstr2dtnummx.mexw32文件复制到Matlab路径上已有的另一个文件夹。

请注意dtstr2dtnummx和datenum之间的字符串格式不同,所以要小心!

对于有兴趣的人,上面的文件夹包含其他有趣的日期转换功能,所以请探索并享受!

Note 5/5/2011:我现在发布了一篇文章,在http://undocumentedmatlab.com/blog/datenum-performance/

上扩展了这个答案

答案 1 :(得分:2)

通常你需要采用系统方法。当我从数据库中提取数千个日期时,我遇到了一个非常类似的问题。事实证明,许多现代数据库(Postgres,Sql server和Oracle是我尝试过的)都可以进行从日期表示到Matlab日期表示的转换,比matlab端的文本日期更快几个数量级。 。如果此数据来自数据库,请考虑数据库端转换!!

答案 2 :(得分:2)

大概如果你关心转换日期所花的时间,你就会转换很多。即使在近期版本的matlab中进行JIT优化,你也可以获得更快的结果调用

datenum(cellarrayofdates, 'yyyy-mm-dd HH:MM:SS');

大于

for i=1:length(cellarrayofdates); datenum(cellarrayofdates{i}, 'yyyy-mm-dd HH:MM:SS'); end

如果您还没有这样做,请从那里开始,因为它允许matlab减少每次调用函数时计算日期格式的开销。

答案 3 :(得分:0)

我意识到这个问题已经过时了。但是,我设法创建的函数比datenum快大约30-40倍。注意:根据使用情况,存在一些小缺陷。如果有人想让我知道,请告诉我。

在1,792,379行上运行:

  • datenum - 11.463186秒
  • datenumjck - 0.300503秒

只需使用textscan读取您的文件,并将日期和时间解释为双精度,并将日期格式输入到我的函数中。

示例:

假设数据格式如下:

Data,2016-03-03,16:15:50;686,0.000000,-0.009500
Data,2016-03-03,16:15:50;696,0.000000,0.006500
Data,2016-03-03,16:15:50;706,0.000000,0.004500
Data,2016-03-03,16:15:50;716,0.000000,-0.006000

阅读数据:

fileID = fopen('myFile.csv','r');
formatSpec = '%*s %f %f %f %f %f %f %f %*[^\n]'; % Ignore first string, save
                                                 % date and time as doubles
                                                 % ignore all other data
data = textscan(fileID,formatSpec,'delimiter',',\t/:;-.\\ ');
fclose(fileID);

指定日期格式并使用datenumjck():

dateFormat = 'yyyy-mm-dd,HH:MM:SS;FFF';
numDate = datenumjck(data,dateFormat);

<强>代码:

function num = datenumjck(data, dateFormat)

n = size(data{1});
dateFormat = textscan(dateFormat,'%s','delimiter',',/:;-.\\');
dateFormat = dateFormat{1};

k = find(strcmp('yyyy', dateFormat),1);
if ~isempty(k)
    y = data{k};
elseif ~isempty(find(strcmp('yy', dateFormat),1))
    y = data{find(strcmp('yy', dateFormat),1)};
else
    y = zeros(n);
end

k = find(strcmp('mm', dateFormat),1);
if ~isempty(k)
    m = data{k};
elseif ~isempty(find(strcmp('mmm', dateFormat),1))
    month = cellfun(@strfind,...
        repmat({'janfebmaraprmayjunjulaugsepoctnovdec'},...
        size(data),lower(data(find(strcmp('mmm', dateFormat),1)))));
    m = (month+2)/3;
else
    m = zeros(n);
end

k = find(strcmp('dd', dateFormat),1);
if ~isempty(k)
    d = data{k};
else
    d = zeros(n);
end

k = find(strcmp('HH', dateFormat),1);
if ~isempty(k)
    H = data{k};
else
    H = zeros(n);
end

k = find(strcmp('MM', dateFormat),1);
if ~isempty(k)
    M = data{k};
else
    M = zeros(n);
end


k = find(strcmp('SS', dateFormat),1);
if ~isempty(k)
    S = data{k};
else
    S = zeros(n);
end

k = find(strcmp('FFF', dateFormat),1);
if ~isempty(k)
    F = data{k};
else
    F = zeros(n);
end

ms = [0,31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334];

num = zeros(n);
for k = 1:n
    num(k) = y(k)*365 + ms(m(k)) + d(k) + floor(y(k)/4)...
        - floor(y(k)/100) + floor(y(k)/400) + (mod(y(k),4)~=0)...
        - (mod(y(k),100)~=0) + (mod(y(k),400)~=0)...
        + (H(k)*3600 + M(k)*60 + S(k) + F(k)/1000)/86400 + 1;
end