我有关于大文本文件输入(~500k行)和后续数据解析的以下性能问题. 考虑具有以下示例性结构的文本文件data.txt,其具有两个标题行可以在文本文件中的某处重新出现的特性: Name Date Val1
考虑具有以下示例性结构的文本文件data.txt,其具有两个标题行可以在文本文件中的某处重新出现的特性:
Name Date Val1 val2 --- ------- ---- ---- BA 2013-09-07 123.123 1232.22 BA 2013-09-08 435.65756 2314.34 BA 2013-09-09 234.2342 21342.342
我编写的代码和以下代码如下:
%# Read in file using textscan, read all values as string inFile = fopen('data.txt','r'); DATA = textscan(inFile, '%s %s %s %s'); fclose(inFile); %# Remove the header lines everywhere in DATA: %# Search indices of the first entry in first cell, i.e. 'Name', and remove %# all lines corresponding to those indices [iHeader,~] = find(strcmp(DATA{1},DATA{1}(1))); for i=1:length(DATA) DATA{i}(iHeader)=[]; end %# Repeat again, the first entry corresponds now to '---' [iHeader,~] = find(strcmp(DATA{1},DATA{1}(1))); for i=1:length(DATA) DATA{i}(iHeader)=[]; end %# Now convert the cells for column Val1 and Val2 in data.txt to doubles %# since they have been read in as strings: for i=3:4 [A] = cellfun(@str2double,DATA{i}); DATA{i} = A; end
我选择在oder中读取所有内容作为字符串,以便能够删除删除DATA中各处的标题行.
停止时间告诉我代码中最慢的部分是转换[A] = cellfun(@ str2double,DATA {i})尽管与str2num相比,str2double已经是更快的选择.第二个最慢的部分是文本扫描.
现在的问题是,有更快的方法来解决这个问题吗?
如果我需要进一步澄清,请告诉我.请原谅我,如果有一个非常明显的解决方案,我还没有看到,我现在只是在Matlab工作了三个星期.
您可以使用名为CommentStyle的文本扫描选项来跳过部分文件(在您的情况下重复的2个标题行),并在一个函数调用中读取您的文件.作为doc says,CommentStyle可以以两种方式使用:单个字符串,例如’%’,用于忽略同一行上字符串后面的字符,或者是两个字符串的单元格数组,例如{‘/ *’,’* / ‘},忽略两个字符串之间的字符(包括行尾).我们将在这里使用第二个选项:删除Name和 – 之间的字符.由于结束字符串由重复字符组成,我们需要指定整个字符串.
inFile = fopen('data.txt','r'); DATA = textscan(inFile, '%s %s %f %f', ... 'Commentstyle', {'Name';'--- ------- ---- ----'}); fclose(inFile);
您可以使用datenum将日期字符串转换为有意义的数字.
DATA_date = datenum(C{2})