从csv中读取存储在行中的大量数据

时间:2015-01-08 11:45:21

标签: matlab csv textscan

我需要从* .csv文件中读取大量数据(~10 ^ 6个数据点)。

  • 数据存储在行
  • 中阅读之前,我无法知道每行有多少数据点以及有多少行
  • 每行的数据点数量可能因每行而不同

所以* .csv文件看起来像这样:

x标头

X1,X2

y标题

y1,y2,y3,...

z标题

Z1,Z2

...

现在我在每行读取字符串并将其拆分为每个逗号。这就是我的代码:

index = 1;
headerLine = textscan(csvFileHandle,'%s',1,'Delimiter','\n');

while ~isempty(headerLine{1})

    dummy = textscan(csvFileHandle,'%s',1,'Delimiter','\n', ...
                'BufSize',2^31 - 1);
    rawData(index) = textscan(dummy{1}{1},'%f','Delimiter',',');
    headerLine = textscan(csvFileHandle,'%s',1,'Delimiter','\n');

    index = index + 1;
end

它有效,但速度很慢。大多数时候在使用textscan分割字符串时使用。 (〜95%)。 我使用示例数据预先分配了rawData,但它几乎没有提供速度。

有没有比我更好的方式来读这样的东西?

如果没有,是否有更快的方法来分割这个字符串?

1 个答案:

答案 0 :(得分:1)

第一个建议:在循环文件时读取单行作为字符串,只需使用fgetl(返回一个漂亮的单个字符串,这样就不会对单元格数组产生影响)。

此外,您可以考虑(如果可能的话),一次性读取所有内容,而不是从文件中重复读取:

output = textscan(fid, '%*s%s','Delimiter','\n');  % skips headers with *

如果文件太大而无法一次完成所有操作,请尝试读取块(例如,一次处理1000行,解析数据)。

为了转换字符串,有str2numstrsplit + str2double的选项,但我唯一能想到的可能比textscan稍微快一点sscanf。由于这不接受分隔符作为单独的输入,因此将其放在格式字符串中(最后一个值不以,结尾,为true,但sscanf可以处理)。

for n = 1:length(output);
    data{n} = sscanf(output{n},'%f,');
end

使用有限的测试数据补丁进行测试表明sscanf更快一些(但可能取决于机器/版本/数据大小)。