从 csv 中读取大量存储在行中的数据
Reading large amount of data stored in lines from csv
我需要从 *.csv-file.
中读取大量数据(~10^6 个数据点)
- 数据按行存储
- 读进去之前不知道每行有多少个数据点,有多少行
- 每行的数据点数量对于每行可以不同
所以 *.csv-file 可能看起来像这样:
x Header
x1,x2
y Header
y1,y2,y3, ...
z Header
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,但它几乎没有带来任何速度。
有没有比我更好的阅读方式?
如果没有,是否有更快的拆分字符串的方法?
第一个建议:在遍历文件时将单行作为字符串读取,只需使用 fgetl
(returns 一个很好的单字符串,所以不要对元胞数组进行操作)。
此外,您可能会考虑(如果可能)一次性读取所有内容,而不是从文件中重复读取:
output = textscan(fid, '%*s%s','Delimiter','\n'); % skips headers with *
如果文件太大以至于您无法一次完成所有操作,请尝试分块读取(例如,一次处理 1000 行,边读边解析数据)。
对于字符串的转换,有 str2num
或 strsplit
+str2double
的选项,但我唯一能想到的可能比 [=16= 稍微快一点] 是 sscanf
。由于这不接受分隔符作为单独的输入,因此将其放入格式字符串中(最后一个值不以 ,
结尾,是的,但是 sscanf
可以处理)。
for n = 1:length(output);
data{n} = sscanf(output{n},'%f,');
end
使用有限的测试数据进行的测试表明 sscanf
更快一些(但可能取决于 machine/version/data 大小)。
我需要从 *.csv-file.
中读取大量数据(~10^6 个数据点)- 数据按行存储
- 读进去之前不知道每行有多少个数据点,有多少行
- 每行的数据点数量对于每行可以不同
所以 *.csv-file 可能看起来像这样:
x Header
x1,x2
y Header
y1,y2,y3, ...
z Header
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,但它几乎没有带来任何速度。
有没有比我更好的阅读方式?
如果没有,是否有更快的拆分字符串的方法?
第一个建议:在遍历文件时将单行作为字符串读取,只需使用 fgetl
(returns 一个很好的单字符串,所以不要对元胞数组进行操作)。
此外,您可能会考虑(如果可能)一次性读取所有内容,而不是从文件中重复读取:
output = textscan(fid, '%*s%s','Delimiter','\n'); % skips headers with *
如果文件太大以至于您无法一次完成所有操作,请尝试分块读取(例如,一次处理 1000 行,边读边解析数据)。
对于字符串的转换,有 str2num
或 strsplit
+str2double
的选项,但我唯一能想到的可能比 [=16= 稍微快一点] 是 sscanf
。由于这不接受分隔符作为单独的输入,因此将其放入格式字符串中(最后一个值不以 ,
结尾,是的,但是 sscanf
可以处理)。
for n = 1:length(output);
data{n} = sscanf(output{n},'%f,');
end
使用有限的测试数据进行的测试表明 sscanf
更快一些(但可能取决于 machine/version/data 大小)。