2010-01-11 73 views
6

我已经编写了一个脚本,将其输出保存为CSV文件供以后参考,但用于导入数据的第二个脚本只需要很长时间就可以读取。在MATLAB中导入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); 

(我知道这可能是非常编写的代码 - 我是工程师,不是程序员,请不要对我大喊大叫 - 改进建议将受到欢迎,虽然)

回答

10

或许,这将使得数据更容易,如果你可以垫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 
3

相反解析字符串一个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; 
+0

+1推荐strtok - 我不知道它存在之前 – Doresoom 2010-01-11 19:44:51

0

Q1)如果你知道列的最大数量,你可以填写与南 也是空的条目,如果所有值均为数字,你真的需要“Item#”列?如果是,则只能使用“#”,因此所有数据都是数字。 Q2)读取num的最快方法。来自没有mex-files的文件的数据是csvread。 我尽量避免使用CSV文件中的字符串,但如果我有,我用我的csv2cell功能:

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

+0

项目#列实际上是文本标签,所以是的,我确实需要它。我应该澄清一点。 – Doresoom 2010-01-11 19:33:15

1

我已经受够了在Matlab读取CSV数据同样的问题,我很惊讶由此得到的支持很少,但后来我找到了导入数据工具。我在r2015b。

在“主页”选项卡的顶部栏上,单击“导入数据”并选择您想要阅读的文件。一个应用程序窗口会想出这样的:

Import Data tool screenshot

在“导入选择”你要“生成函数”的选项,它给你相当多的自定义选项,包括如何填补空白单元格,以及您希望输出数据结构是什么。另外它由MathWorks编写,所以它可能利用最快的可用方法来读取csv文件。这几乎是我的档案中的瞬间。