假设我有一个纯文本文件test.dat
:
foo bar baz
qux ham spam
我知道想要将它加载到Octave(或者必要时是Matlab)作为二维单元格数组,保留以空格和换行符编码的结构。根据我对the documentation的理解,以下应该是要走的路:
format = '%s';
file = fopen('test.dat');
data = textscan(file,format);
fclose(file);
disp(data);
然而,这仅将数据加载为一维数组:
{
[1,1] =
{
[1,1] = foo
[2,1] = bar
[3,1] = baz
[4,1] = qux
[5,1] = ham
[6,1] = spam
}
}
明确指定Delimiter
,Whitespace
和EndOfLine
没有帮助(后者有什么意义呢?);也没有使用其他加载函数,如textread
或dlmread
。上面的工作是使用format = '%s%s%s'
做了什么,但这要求我以某种方式确定列的数量,该函数应该能够自己完成。
因此我问:是否有内置功能能够满足我的需求?我对自己编写此类功能的方式不感兴趣 - 我有信心我可以做到这一点,但这正是我想要避免的(因为我需要用它来展示良好的练习,因此不能重新发明轮子)。
相关Q& As(知道列数的所有工作):
答案 0 :(得分:5)
您可以使用readtable
data = readtable('test.txt', 'ReadVariableNames', false, 'Delimiter', ' ')
输出:
Var1 Var2 Var3
_____ _____ ______
'foo' 'bar' 'baz'
'qux' 'ham' 'spam'
如果你想要一个单元格,而不是一张桌子,你可以使用
data = table2cell( data );
>> data = {'foo' 'bar' 'baz'
'qux' 'ham' 'spam'}
我不确定readtable
是否为Octave方法,它似乎是on GitHub但我无法检查安装。它在2013b中被引入Matlab。
您可以使用较低级别的操作,逐行阅读
fid = fopen('test.txt','r');
data = {};
while ~feof(fid)
line = fgets(fid); % Read line
A = strsplit(line, ' '); % Split on spaces
data(end+1, :) = A; % Append to output
end
fclose(fid);
>> data = {'foo' 'bar' 'baz'
'qux' 'ham' 'spam'}
此方法假定data
的每一行将具有相同数量的元素(每行中的分隔符数相同)。如果你不能这样做,那么更安全的方法是做data{end+1,1} = A
,然后再分割线。
答案 1 :(得分:3)
在Octave中,您可以使用包io
中的csv2cell:
pkg load io
result = csv2cell('test.dat',' ')
答案 2 :(得分:0)
我建议您查看fgetl()或fgets()函数。 基本上你读了文件的行,然后你可以用textscan()应用你的代码并得到“列”。
答案 3 :(得分:0)
我有同样的问题。在Matlab中,readtable.m对我来说很慢,并且fgetl示例正在循环调整大小。 但也许可以接受的解决方案基于此论坛帖子: https://de.mathworks.com/matlabcentral/answers/476483-how-to-use-textscan-on-a-cell-array-without-a-loop
因此,至少在较新的Matlab中:
fid=fopen(file,'r');
data=textscan(fid,'%s','Delimiter','\r\n');
fclose(fid);
data=split(data{1},';',1);
我还没有测试split.m处理大数据的速度。