Octave / Matlab - 优化CSV导入 - 加速datenum

时间:2015-01-08 01:17:28

标签: matlab csv optimization file-io octave

我一直对在Octave中导入CSV文件感到非常沮丧。

这是我最近的实施。 CSV文件的格式为:

"Business Unit" | "Date" | "Customer ID" | data 1 | ... | data 19 | "Description"

其中数据j j = 1,2,...,19 )是您感兴趣的客户数据。

我想根据相应的日期是否在dBegin和dEnd范围内来提取行的子集,然后将子集输出到新文件extractedData.csv,并删除业务单位和描述。

我之前的实现是逐行循环,检查每一行的日期条件。但是,它太慢了。所以我建议将数据加载成碎片以加快处理速度。这个文件超过一百万行(大约1GB),甚至这个实现也是永远的(在撰写本文时它仍然没有在15分钟后完成,我首先在较小的文件上测试它以确保它有效)。 / p>

一些建议将不胜感激!我无法理解的一件事是R如何设置如此快速地导入数据而不会崩溃(即data_set = read.table("rawData.csv", sep=",")在R中按预期工作,但Octave中的等效物由于内存不足而迅速崩溃,因此迫使我进入一个更像手动的实现,如下所示。我正在为两者使用32位版本。

    dBegin = datenum('12/01/2013');
    dEnd = datenum('05/30/2014');
    fName1 = 'rawData.csv';
    fName2 = 'extractedData.csv';
    fID1 = fopen(fName1, 'r');
    fID2 = fopen(fName2, 'w');
    formatSpec = '%s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s'; % load everything as a string
    headerString = strjoin(strtok(strsplit(fgetl(fID1), ','), '"'), ','); % read first row with header information
    fprintf(fID2, '%s', headerString); % output headers to new file
    N = 100000; % we'll read N rows at a time
    while ~feof(fID1)
      C = textscan(fID1, formatSpec, N, 'Delimiter', ','); % read a block of N rows
      dateVector = datenum(strtok(C{1,2}, '"')); % convert the short date strings in column 2 into numerical values
      indexVector = find(dateVector >= dBegin & dateVector <= dEnd); % determine which rows fall in the correct date range
      if (length(indexVector) == 0)
        continue; % read the next block of data if there are no matching dates
      endif
      D = num2str(datenum(C{1,2}(indexVector,1))); % Create a new cell array with first column as dates (in numerical format)
      for i = 2:19
        D(:, i) = C{1,i+1}(indexVector, 1); % append all of the other corresponding columns to each row
      endfor
      for i = 1:length(indexVector) % print D row-by-row to the new file
        fprintf(fID2, '%s\n', strjoin(strtok(D(i, :), '"'), ',')); % cellfun(@num2str, D, 'UniformOutput', 0)
      endfor
    endwhile
    fclose(fID1);
    fclose(fID2);

修改

经过调试,我发现这条线相对于其他线路需要花费大量时间来执行:

dateVector = datenum(strtok(C{1,2}, '"'));

替换上面的行
C{1,2} = strtok(C{1,2}, '"');
dateVector = datenum(C{1,2});

显示调用datenum会降低程序速度。有什么方法可以解决这个问题吗?

0 个答案:

没有答案