我正在尝试将大文本文件(几百万行)读入Matlab。最初我使用的是importdata(file_name),这似乎是一个简洁的解决方案。但是我需要使用Matlab 7(是的,我知道它的旧版本),似乎不支持importdata。因此,我尝试了以下内容:
while ~feof(fid)
fline = fgetl(fid);
fdata{1,lno} = fline ;
lno = lno + 1;
end
但这真的很慢。我猜它是因为它在每次迭代时调整数组大小。有没有更好的方法来做到这一点。请记住,输入数据的前20行是字符串类型数据,其余数据是3到6列十六进制值。
答案 0 :(得分:5)
你将不得不做一些重塑,但另一个选择是你可以使用fread。 但正如所提到的,这基本上将您锁定为矩形导入。所以另一个选择是使用textscan。正如我在另一篇文章中提到的,我不是百分之百确定实施的时候,我所知道的是你没有“importdata()”
fid = fopen('textfile.txt')
Out = textscan(fid,'%s','delimiter',sprintf('\n'));
fclose(fid)
通过使用文本扫描,您将能够获得每行的单元格数组,然后您可以根据需要进行操作。正如我在评论中所说的那样,线条长度是否相同并不重要。现在,您可以更快地解析单元阵列。但正如gnovice所提到的,他也确实有一个非常优雅的解决方案,你可能不得不关注内存需求。
如果你能避免它,你永远不想在matlab中使用的一件事就是循环结构。它们在C / C ++等方面很快,但在matlab中,它们是获取目标的最慢方式。
编辑:只是看了一下,看起来文本可以在版本7(R14)中逐字实现,所以如果那就是你拥有的,你应该很好用。
答案 1 :(得分:2)
我看到两个选项:
答案 2 :(得分:2)
一种解决方案是将文件的全部内容作为带有FSCANF的字符串读取,使用MAT2CELL将字符串拆分为出现换行符的点的单个单元格,删除多余的空格在STRTRIM的末尾,然后根据需要处理每个单元格中的字符串数据。例如,使用此示例文本文件'junk.txt'
:
hi
hello
1 2 3
FF 00 FF
12 A6 22 20 20 20
FF FF FF
以下代码将每行放在单元格数组cellData
的单元格中:
>> fid = fopen('junk.txt','r');
>> strData = fscanf(fid,'%c');
>> fclose(fid);
>> nCharPerLine = diff([0 find(strData == char(10)) numel(strData)]);
>> cellData = strtrim(mat2cell(strData,1,nCharPerLine))
cellData =
'hi' 'hello' '1 2 3' 'FF 00 FF' '12 A6 22 20 20 20' 'FF FF FF'
现在,如果要将所有十六进制数据(我的示例数据文件中的第3行到第6行)从字符串转换为数字向量,您可以使用CELLFUN和SSCANF,如下所示:< / p>
>> cellData(3:end) = cellfun(@(s) {sscanf(s,'%x',[1 inf])},cellData(3:end));
>> cellData{3:end} %# Display contents
ans =
1 2 3
ans =
255 0 255
ans =
18 166 34 32 32 32
ans =
255 255 255
注意:由于您正在处理此类大型数组,因此您必须注意变量的amount of memory being used。上述解决方案是矢量化的,但可能占用大量内存。在创建strData
时,您可能需要覆盖clear大变量,例如cellData
。或者,您可以循环遍历nCharPerLine
中的元素,并将较大字符串strData
的每个段单独处理为您需要的向量,您可以预先分配,因为您知道如何您拥有的许多数据行(即nDataLines = numel(nCharPerLine)-nHeaderLines;
)。