matlab从文件中读取混合数据

时间:2016-11-25 16:34:46

标签: matlab

我是matlab的新手。我一直在阅读文档,但可以弄清楚为什么matlab没有正确读取文件中的字符串。我想要做的是从文件中读取混合数据类型。一些示例数据是:

t a e incl lasc aper meanan truean rupnode rdnnode name
0.000000    1.2712052487 0.8899021688 22.2458  265.2511471042  322.1539251184  -13.6281352271 -130.986 0.155342 0.889756 phaet_000018 
0.000000    1.2712052478 0.8899021575 22.2458  265.2511428392  322.1539270642  -13.6281369694 -130.986 0.155342 0.889756 phaet_000044 
0.000000    1.2712052496 0.8899021868 22.2458  265.2511587897  322.1539149438  -13.6281365049 -130.986 0.155342 0.889755 phaet_000006 

第一行是标题。所以这就是我到目前为止所做的:

fid = fopen('data.dat');
header = fgetl(fid); # I read the header

Now I read the data:

data = fscanf(fid,'%f %f %f %f %f %f %f %f %f %f %s',[11 inf]);
data1 = data';
fclose(fid); 

我现在可以访问第一个元素:

data1(1,1)

然而,当我这样做时:

data(1,11)

而不是phaet_000018我得到一个数字(112)。知道我做错了吗?

1 个答案:

答案 0 :(得分:0)

您的代码存在一些问题。

首先,您对sizeAfscanf输入是向后的。带矢量输入的sizeA定义为:

  

最多读取m*n个数值或字符字段。 n可以是Inf,但m不能。输出Am - 按 - n按列顺序填充。

所以,您已经要求fscanf为您提供11行和任意数量的列。您不能拥有Inf行规范,因此您希望完全删除第三个输入,然后reshape您的数据。

例如:

fid = fopen('data.dat');
header = fgetl(fid);

data = fscanf(fid,'%f %f %f %f %f %f %f %f %f %f %s');
fclose(fid); 

% We just happen to know this explicitly, not knowledge to generally assume
ncols = 22;

% Reshape and transpose
data = reshape(data, ncols, []).';

给我们一个3 x 22 data数组,这有点像我们想要的。

那么额外的列来自何处?对于%s字段,fscanf读取字符串直到遇到空格。因为fscanf的输出是数字数组,所以它必须将此字符串转换为数字值,因此它将每个字符转换为其等效数字(double(letter))并将其输出到矩阵中。

使用上面的data矩阵作为示例,我们有:

>> char(data(1, 11:end))

ans =

phaet_000018

考虑到这一点,您的初始代码恰好起作用,因为所有字符串的长度都相同。如果我们更改一个或多个字符串的长度,则此数据导入将失败:

Error using reshape
Product of known dimensions, 22, not divisible into total number of elements, 65.

Error in testcode (line 11)
data = reshape(data, ncols, []).';

那么我们可以做些什么呢?如果您需要来自您的数据的字符串,我建议您尝试textscan

fid = fopen('data.dat');
header = fgetl(fid);

data = textscan(fid, '%f %f %f %f %f %f %f %f %f %f %s');
fclose(fid);

这会将您的数据读入1x11 cell array,其中每列对应数据中的一列:

>> data{1}  % t

ans =

     0
     0
     0

要收集数字数据,您可以遍历单元格数组,或者可以使用'CollectOutput'中的textscan标记:

fid = fopen('data.dat');
header = fgetl(fid);

data = textscan(fid, '%f %f %f %f %f %f %f %f %f %f %s', 'CollectOutput', true);
fclose(fid);

将输出1x2单元格数组,其中data{1}是您的数字数组,data{2}是包含字符串的单元格数组:

>> data{1}  % Numeric data

ans =

         0    1.2712    0.8899   22.2458  265.2511  322.1539  -13.6281 -130.9860    0.1553    0.8898
         0    1.2712    0.8899   22.2458  265.2511  322.1539  -13.6281 -130.9860    0.1553    0.8898
         0    1.2712    0.8899   22.2458  265.2512  322.1539  -13.6281 -130.9860    0.1553    0.8898

>> data{2}  % Strings

ans =

  3×1 cell array

    'phaet_000018'
    'phaet_000044'
    'phaet_000006'