MATLAB:从文件中解析文本,并转换为数学集

时间:2012-12-02 03:58:52

标签: parsing matlab

.txt用一个我不关心的可变长度字符串开始每一行,后跟空格分隔的ID:

somegarbage 34532 2034 203 4 30403


garbage 2 45 2342 23 33503434
garbagethird 2 

第2行和第3行是空的。

数据文件一行上的所有ID都应该是

  1. 被推入数学集合(即{。},其中元素的顺序无关紧要)
  2. 分配给V [linenumber]。
  3. 读入后的示例查询:

    V[5]
      -> {2}
    V[2]
      -> {}
    

    我需要哪些功能和数据结构?

    如果MATLAB没有 set 数据结构,是否有任何接近,或者我是否必须求助于二​​维数组?

2 个答案:

答案 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)

有两个功能非常适合此目的:textreadtextscan。它们都接收一个格式字符串,该字符串指定输入文本文件的每一行中的参数模式。

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循环迭代令牌的简单方法。它还使解决方案更加优雅,而且不那么繁琐。