我需要从* .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,但它几乎没有提供速度。
有没有比我更好的方式来读这样的东西?
如果没有,是否有更快的方法来分割这个字符串?
答案 0 :(得分:1)
第一个建议:在循环文件时读取单行作为字符串,只需使用fgetl
(返回一个漂亮的单个字符串,这样就不会对单元格数组产生影响)。
此外,您可以考虑(如果可能的话),一次性读取所有内容,而不是从文件中重复读取:
output = textscan(fid, '%*s%s','Delimiter','\n'); % skips headers with *
如果文件太大而无法一次完成所有操作,请尝试读取块(例如,一次处理1000行,解析数据)。
为了转换字符串,有str2num
或strsplit
+ str2double
的选项,但我唯一能想到的可能比textscan
稍微快一点sscanf
。由于这不接受分隔符作为单独的输入,因此将其放在格式字符串中(最后一个值不以,
结尾,为true,但sscanf
可以处理)。
for n = 1:length(output);
data{n} = sscanf(output{n},'%f,');
end
使用有限的测试数据补丁进行测试表明sscanf
更快一些(但可能取决于机器/版本/数据大小)。