.txt用一个我不关心的可变长度字符串开始每一行,后跟空格分隔的ID:
somegarbage 34532 2034 203 4 30403
garbage 2 45 2342 23 33503434
garbagethird 2
第2行和第3行是空的。
数据文件一行上的所有ID都应该是
读入后的示例查询:
V[5]
-> {2}
V[2]
-> {}
我需要哪些功能和数据结构?
如果MATLAB没有 set 数据结构,是否有任何接近,或者我是否必须求助于二维数组?
答案 0 :(得分:1)
根据您打算对数据进行的操作,这可能是方法:
V=importdata('A.txt')
V =
data: [2x6 double]
textdata: {2x1 cell}
rowheaders: {2x1 cell}
V将是一个包含所有“ID”的字段数据的结构。
然后,您可以使用V.data(linenumber,:)
来获取想要混乱的行。
V.data(1,:)
ans =
34532 2034 203 4 30403 3333
行可以是不等长的:
V.data(2,:)
ans =
2 45 2342 23 33503434 NaN
改进的解决方案:
fid = fopen('A.txt');
tline = fgets(fid);
counter=1;
while ischar(tline)
v{counter} = strread(char(tline),'%s','delimiter',' ');
if ~isempty(v{counter})
v{counter}=v{counter}(2:end);
else
v{counter}={};
end
tline = fgets(fid);
V{counter}=cellfun(@str2double, v{counter}');
counter=counter+1;
end
fclose(fid);
此解决方案保留空行:
V{1}
ans =
34532 2034 203 4 30403
V{2}
ans =
[]
答案 1 :(得分:1)
有两个功能非常适合此目的:textread
和textscan
。它们都接收一个格式字符串,该字符串指定输入文本文件的每一行中的参数模式。
textread
的解决方案: textread
要求输出变量的数量与每行中读取的参数数量相匹配,因此您可以沿着这些行执行某些操作:
[col1, col2, col3, col4, col5, col6] = textread('myfile.txt', '%s %d %d %d %d');
V = [col2, col3, col4, col5, col6]
这会产生:
V =
34532 2034 203 4 30403
2 45 2342 23 33503434
基本上你拥有的是矩阵(即一个数组数组),其中每一行对应于输入文本文件中的一行。要访问其中一行,您只需执行V(row_index, :)
,例如:
V(1, :) =
34532 2034 203 4 30403
textscan
的解决方案: textscan
需要手动打开文件。它返回一个单元格数组(实际上是一个特殊类型的数组,可以在同一个集合中保存多种类型的变量,例如带有数字的字符串)。要获得与textread
相同的矩阵,我们使用逗号分隔列表和简单连接,如下所示:
fid = fopen('myfile.txt');
C = textscan(fid, '%s %d %d %d %d %d')
V = [C{2:6}]
fclose(fid);
现在V
应该包含与第一个示例中相同的元素。
如果解析参数的数量未知,最好将该行作为整个字符串读取,并用regexp
解析它:
fid = fopen('myfile.txt');
C = textscan(fid, '%s', 'Delimiter', '');
V = C{1};
for i = 1:numel(V)
V{i} = cellfun(@str2num, regexp(V{i}, '\d*', 'match'));
end
fclose(fid);
在这种情况下,输出V
将是cell array(因为矩阵需要固定每个元素的数量)。单元阵列中的每个单元都是一个数字数组(即一个向量),可能具有不同的长度。对于您的示例,结果将是一个3乘1的单元格数组(忽略空行):
V =
[34532 2034 203 4 30403]
[ 2 45 2342 23 33503434]
[ 2]
在这里,您可以使用大括号({}
)访问每一行的元素,例如V{2}
:
ans =
[ 2 45 2342 23 33503434]
建议:格式模式和正则表达式极大地简化了字符串解析,并且在MATLAB中通常优先使用for
循环迭代令牌的简单方法。它还使解决方案更加优雅,而且不那么繁琐。