Matlab将txt文件读入数组

int*_*ntl 4 arrays matlab fopen text-files multidimensional-array

我有一个文本文件,其中包含以下格式的信息:

Name1 34 25 36 46
Name1 23 53 15 86
Name1 25 25 87 35
Name2 76 22 44 55
Name2 88 88 88 88
Name3 11 11 11 11
Name3 55 66 88 88
Name3 88 88 88 88
Name3 00 00 00 00
Run Code Online (Sandbox Code Playgroud)

有不同的"名称",我必须将每个名称排列成一个数组插槽.然后,我需要另一种方法将与每行关联的日期分配到该特定位置.因此,例如,第一个Name1可能有数组{0},但我还需要以某种方式关联34,24,36和46.我还需要区分不同的名字.做这个的最好方式是什么?2x2阵列似乎不是解决方案.

到目前为止我所拥有的是这样的:

%# read the whole file to a temporary cell array
fid = fopen(filename,'rt');
tmp = textscan(fid,'%s','Delimiter','\n');
fclose(fid);

%# remove the lines starting with headerline
tmp = tmp{1};
idx = cellfun(@(x) strcmp(x(1:10),'headerline'), tmp);
tmp(idx) = [];

%# split and concatenate the rest
result = regexp(tmp,' ','split');
result = cat(1,result{:});

%# delete temporary array (if you want)
clear tmp
Run Code Online (Sandbox Code Playgroud)

礼貌:在Matlab中读取txt文件

有人可以告诉我安排信息的最佳方式吗?谢谢,非常感谢帮助.

Rod*_*uis 5

从代码来看,你为什么不用

fid = fopen(filename,'rt');
tmp = textscan(fid, '%s %d %d %d %d', 'Headerlines', 10);
fclose(fid);
Run Code Online (Sandbox Code Playgroud)

textscan默认情况下,使用空格和换行符作为分隔符.如果明确地将换行符作为分隔符,则将空格作为分隔符和可移植性(Windows通常\r\n用作单个换行符,而Unix派生的操作系统使用\n).因此,根据您的数据,只需将其删除即可.

然后你跳过篮球去除10个标题,虽然textscan已经有一个很好的烘焙选项.因此,不需要这些步骤.你继续通过regexp一个空格作为分隔符来分割东西,但由于textscan已经在空间上分裂,所以也不需要.

所以,使用上面的三行,你就会得到

tmp = 
    {9x1 cell}    [9x1 int32]    [9x1 int32]    [9x1 int32]    [9x1 int32]
Run Code Online (Sandbox Code Playgroud)

现在,现在更方便地存储数据.我可以想到两种方式:

  1. 细胞阵列
  2. 结构

对于两者,您必须首先找到唯一的名称:

[names, inds] = unique(tmp{1});
Run Code Online (Sandbox Code Playgroud)

使用单元格数组

这将为您提供按名称排序的数据的单元格数组:

data = [tmp{2:end}];
results = arrayfun(@(x) data(strcmp(tmp{1},x),:), ...
            names, 'uniformoutput', false);
Run Code Online (Sandbox Code Playgroud)

现在您可以索引results如下:

results{3}(1,4)   %# for the 4th '11' for 'Name3' 
Run Code Online (Sandbox Code Playgroud)

请记住,Matlab是基于1的,因此它a(3)表示第3个元素a,而不是第4 个元素.

命令细分:

  1. 该函数arrayfun循环遍历输入数组的元素,将函数应用于每个元素,并将结果收集在常规数组(如果可能)或单元数组中(当不可能时(错误)和给定时'uniformoutput', false).这有点像 - foreach构造.

  2. 使输入数组等于names第一步中找到的唯一值,技巧是在函数中应用于每个名称.该函数@(x) data(strcmp(tmp{1},x),:)首先使用查找tmp{1}(包含所有名称的数组)中给定名称的索引strcmp.然后使用这些索引来索引data = [tmp{2:end}],即所有其他数组.

  3. 然后将每个单独的唯一名称的结果存储在单元阵列中results.

使用结构

您可以更进一步,使用单元格数组results来获得更易读的数据结构.应用完所有前面的步骤后,执行以下步骤:

for ii = 1:numel(names)
    output.(names{ii}) = results{ii}; end
Run Code Online (Sandbox Code Playgroud)

现在您可以按名称引用您的数据:

output.Name3(1,4)   %# to index the 4th '11' from 'Name3'
Run Code Online (Sandbox Code Playgroud)

语法your_struct.('someString')称为动态结构引用.它在被称为的结构中引用或创建一个字段.your_strucsomeString

现在,如果names{ii}包含要删除的下划线,则可以定义

camelCase = @(x) regexprep(x, '_+(\w?)', '${upper($1)}')
Run Code Online (Sandbox Code Playgroud)

要么

camelCase = @(x) regexprep(x, ' +(\w?)', '${upper($1)}')
Run Code Online (Sandbox Code Playgroud)

对于空间.然后用

for ii = 1:numel(names)
    output.( camelCase(names{ii}) ) = results{ii}; end
Run Code Online (Sandbox Code Playgroud)

最后一个对这些家伙的称赞.