我有一个数据文件,每行数据量不一,我想将其作为数组加载到Matlab中。例如,假设数据文件看起来像
1 2
3 4 5 6
7
8 9 10
我想把它作为一个看起来像
的数组读入Matlab1 2 nan nan
3 4 5 6
7 nan nan nan
8 9 10 nan
我可以通过在文件的所有行上执行for循环来完成此操作,但我的文件非常大,我正在寻找一个有效的解决方案。任何想法都将受到高度赞赏。如果有帮助,我也知道文件中最大行长的上限。
答案 0 :(得分:2)
此技术使用 dlmread
,它固有地将空位置转换为零,然后我们需要根据需要将这些位置转换为NaN以获得所需的输出。
<强>代码强>
out = dlmread(textfile_path, ' ') %%// textfile_path is path to your text file
out(out==0)=NaN %%// out is your desired output
<强>输入强>
1 2
3 4 5 6
7
8 9 10
<强>输出强>
out =
1 2 NaN NaN
3 4 5 6
7 NaN NaN NaN
8 9 10 NaN
这种方法围绕使用 textscan
将数据导入到按原样保留零的单元格列数组,并将空位置作为NaN。唯一的问题是,对于最后一行,由于没有任何空位(如果最后一行不是最长的一行),则长度不等于行数。同样,我们需要额外的代码行。
方法1:
<强>代码强>
fid = fopen(textfile_path,'r'); %%// textfile_path is path to your text file
data1 = textscan(fid,'');
fclose(fid);
lens = cellfun(@numel,data1)
out = NaN(max(lens),numel(lens)) %%// out will be your output
for k = 1:numel(lens)
out(1:lens(k),k) = data1{:,k}
end
方法2(更短版本):
<强>代码强>
fid = fopen(textfile_path,'r'); %%// textfile_path is path to your text file
data1 = textscan(fid,'');
fclose(fid);
n1 = find(diff(cellfun(@numel,data1))~=0)
%%// out will be your output
out = [horzcat(data1{:,[1 n1]}) [horzcat(data1{:,[n1+1:end]}) ; NaN(1,numel(data1)-n1)]]
<强>输入强>
1 2 3
4 0
5 6 0 7 8
0 0
<强>输出强>
out =
1 2 3 NaN NaN
4 0 NaN NaN NaN
5 6 0 7 8
0 0 NaN NaN NaN
答案 1 :(得分:2)
虽然如果您的文本文件中没有任何零值,Divakar的答案仍然有效,但通常情况并非如此。例如,如果您的文本数组是
1 2 3
4 0
5 6 0 7 8
然后Divakar的结果将是:
1 2 3 nan nan
4 nan nan nan nan
5 6 nan 7 8
而你真的想要:
1 2 3 nan nan
4 0 nan nan nan
5 6 0 7 8
实现这一点的最简单方法是打开dlmread函数(只需在文本编辑器中键入dlmread并按Ctrl + D将其打开)。请确保将此文件另存为您使用其他名称(即dlmread_nan.m)工作的目录中的单独文件。
转到代码的这一部分(我的版本中的第126行):
if isempty(delimiter)
result = textscan(fid,'',nrows,'headerlines',r,'headercolumns',c,...
'returnonerror',0,'emptyvalue',0, 'CollectOutput', true);
else
delimiter = sprintf(delimiter);
whitespace = setdiff(sprintf(' \b\t'),delimiter);
result = textscan(fid,'',nrows,...
'delimiter',delimiter,'whitespace',whitespace, ...
'headerlines',r,'headercolumns',c,...
'returnonerror',0,'emptyvalue',0,'CollectOutput', true);
end
并在&#39; emptyvalue&#39;之后更改值在两种情况下都是NaN而不是0.保存文件。它应该是这样的:
if isempty(delimiter)
result = textscan(fid,'',nrows,'headerlines',r,'headercolumns',c,...
'returnonerror',0,'emptyvalue',NaN, 'CollectOutput', true);
else
delimiter = sprintf(delimiter);
whitespace = setdiff(sprintf(' \b\t'),delimiter);
result = textscan(fid,'',nrows,...
'delimiter',delimiter,'whitespace',whitespace, ...
'headerlines',r,'headercolumns',c,...
'returnonerror',0,'emptyvalue',NaN,'CollectOutput', true);
end
要获取数组,请使用:
result = dlmread_nan('text.txt', ' ');
%%//This will give you exactly what you're looking for.
这有点麻烦,但是通过从MATLAB库中复制,它可能比自己从头开始编写更加强大和无错误。
答案 2 :(得分:0)
在这种情况下?
<强>输入强>
1 2 3 6
4 5
1 0 7 8
0 0 5
怎么办?
Textscan会很危险,因为它不会保留数字位置