【问题标题】:Fastest way to import CSV files in MATLAB在 MATLAB 中导入 CSV 文件的最快方法
【发布时间】:2011-01-03 20:43:05
【问题描述】:

我编写了一个脚本,将其输出保存到 CSV 文件以供以后参考,但是用于导入数据的第二个脚本需要花费大量时间才能将其读回。

数据格式如下:

Item1,val1,val2,val3
Item2,val4,val5,val6,val7
Item3,val8,val9

标题位于最左侧列,数据值占据该行的其余部分。一个主要困难是每个测试项目的数据值数组可以是不同的长度。我会将其保存为结构,但我需要能够在 MATLAB 环境之外对其进行编辑,因为有时我必须在未安装 MATLAB 的计算机上删除不良数据行。所以真的,我的问题之一是:我应该以不同的格式保存数据吗?

问题的第二部分: 我试过importdatacsvreaddlmread,但我不确定哪个最好,或者是否有更好的解决方案。现在我正在使用我自己的脚本,使用循环和fgetl,这对于大文件来说非常慢。有什么建议吗?

function [data,headers]=csvreader(filename); %V1_1
 fid=fopen(filename,'r');
 data={};
 headers={};
 count=1;
 while 1
      textline=fgetl(fid);
      if ~ischar(textline),   break,   end
      nextchar=textline(1);
      idx=1;
      while nextchar~=','
        headers{count}(idx)=textline(1);
        idx=idx+1;
        textline(1)=[];
        nextchar=textline(1);
      end
      textline(1)=[];
      data{count}=str2num(textline);
      count=count+1;
 end
 fclose(fid);

(我知道这可能是写得很糟糕的代码 - 我是工程师,而不是程序员,请不要对我大喊大叫 - 欢迎任何改进建议。)

【问题讨论】:

    标签: matlab file-io csv data-import


    【解决方案1】:

    如果您可以在第一个脚本创建文件时使用 NaN 值填充文件,可能会使数据更易于阅读:

    Item1,1,2,3,NaN
    Item2,4,5,6,7
    Item3,8,9,NaN,NaN
    

    或者您甚至可以只打印空字段:

    Item1,1,2,3,
    Item2,4,5,6,7
    Item3,8,9,,
    

    当然,为了正确填充,您需要事先知道所有项目的最大值数是多少。对于上述任何一种格式,您都可以使用其中一个标准文件读取函数,例如 TEXTSCAN

    >> fid = fopen('uneven_data.txt','rt');
    >> C = textscan(fid,'%s %f %f %f %f','Delimiter',',','CollectOutput',1);
    >> fclose(fid);
    >> C{1}
    
    ans = 
    
        'Item1'
        'Item2'
        'Item3'
    
    >> C{2}
    
    ans =
    
         1     2     3   NaN  %# TEXTSCAN sets empty fields to NaN anyway
         4     5     6     7
         8     9   NaN   NaN
    

    【讨论】:

      【解决方案2】:

      而不是一次解析字符串textline一个字符。例如,您可以使用 strtok 来分解字符串

      stringParts = {};
      tline = fgetl(fid);
      if ~ischar(tline), break, end
      i=1;
      while 1
          [stringParts{i},r]=strtok(tline,',');
          tline=r;
          i=i+1;
          if isempty(r), break; end
      end
      
      % store the header
      headers{count} = stringParts{1};
      
      % convert the data into numbers
      for j=2:length(stringParts)
          data{count}(j-1) = str2double(stringParts{j});
      end
      count=count+1;
      

      【讨论】:

        【解决方案3】:

        我在 Matlab 中读取 csv 数据时遇到了同样的问题,我很惊讶对此的支持如此之少,但后来我才找到了导入数据工具。我在 r2015b。

        在“主页”选项卡的顶部栏中,点击“导入数据”并选择您要阅读的文件。应用程序窗口将如下所示:

        Import Data tool screenshot

        在“导入选择”下,您可以选择“生成函数”,它为您提供了相当多的自定义选项,包括如何填充空单元格,以及您希望输出数据结构是什么。加上它是由 MathWorks 编写的,所以它可能使用最快的方法来读取 csv 文件。在我的文件中几乎是瞬间完成的。

        【讨论】:

          【解决方案4】:

          Q1)如果您知道最大列数,您可以用 NaN 填充空条目 另外,如果所有值都是数字,你真的需要“Item#”列吗?如果是,则只能使用“#”,因此所有数据都是数字。

          Q2) 读取 num 的最快方法。来自没有 mex 文件的文件的数据是 csvread。 我尽量避免在 csv 文件中使用字符串,但如果必须,我会使用我的 csv2cell 函数:

          http://www.mathworks.com/matlabcentral/fileexchange/20135-csv2cell

          【讨论】:

          • Item# 列实际上是文本标签,所以是的,我确实需要它。我可能应该澄清一下。
          猜你喜欢
          • 1970-01-01
          • 2017-04-20
          • 2012-08-14
          • 1970-01-01
          • 2022-07-10
          • 2022-07-25
          • 2017-07-08
          • 1970-01-01
          相关资源
          最近更新 更多