Matlab将txt文件读入数组 [英] Matlab read in txt file into array

查看:354
本文介绍了Matlab将txt文件读入数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a text file with the following format of information:

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

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

There are different "Names" and I have to arrange each name into an array slot. I would then need another way to allocate the date associated with each row to that specific spot. So for example, the first Name1 may have array{0}, but I would also need to associate the 34, 24, 36, and 46 somehow. I would also need to distinguish the different names from each other. What is the best way to do this? a 2x2 array does not seem to be the solution.

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

What I have so far is something along the lines of this:

%# 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

礼貌:在 Matlab 中读取 txt 文件

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

Could someone please tell me the best way to arrange the information? Thanks, help is much appreciated.

推荐答案

从代码上看,为什么不用

Judging from the code, why don't you use

fid = fopen(filename,'rt');
tmp = textscan(fid, '%s %d %d %d %d', 'Headerlines', 10);
fclose(fid);

textscan 默认使用空格和换行符作为分隔符.如果你显式地给换行符作为分隔符,你就会失去作为分隔符的空间和可移植性(Windows 通常使用 \r\n 作为单个换行符,而 Unix 派生的操作系统使用 \n).因此,鉴于您的数据,只需将其忽略即可.

textscan uses space and newline as delimiters by default. If you give newline as delimiter explicitly, you loose the space as delimiter, and the portability (Windows often uses \r\n as a single newline, whereas Unix-derived OSes use \n). So, given your data, just leave it out.

然后您跳过箍以删除 10 个标题行,而 textscan 已经有一个很好的内置选项.因此,不需要这些步骤.您可以通过使用空格作为分隔符的 regexp 来拆分内容,但是由于 textscan 已经在空格上拆分,因此也不需要.

Then you jump through hoops to remove 10 headerlines, while textscan already has a nice baked-in option for that. So, those steps aren't needed. You proceed by splitting the stuff by a pass through regexp with a space as delimiter, but since textscan already splits on space, that's not needed either.

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

So, using the three lines above, you'll get

tmp = 
    {9x1 cell}    [9x1 int32]    [9x1 int32]    [9x1 int32]    [9x1 int32]

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

Now, now to store the data more conveniently. I can think of two ways:

  1. 元胞数组
  2. 结构

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

For both, you'll have to find the unique names first:

[names, inds] = unique(tmp{1});

使用元胞数组

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

Using cell arrays

This will give you a cell-array of the data sorted by name:

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

现在您可以按如下方式索引results:

Now you can index into results as follows:

results{3}(1,4)   %# for the 4th '11' for 'Name3' 

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

Remember that Matlab is 1-based, so that a(3) indicates the 3rd element of a, not the 4th.

命令分解:

  1. 函数 arrayfun 遍历输入数组的元素,对每个元素应用一个函数,然后将结果收集到常规数组(如果可能)或元胞数组中(当不可能(错误)并且给出 'uniformoutput', false 时).它有点像 foreach 结构.

  1. The function arrayfun loops through the elements of the input array, applies a function to each element, and collects the results in either a regular array (if possible) or a cell-array (when impossible (error) and when given 'uniformoutput', false). It's a bit like a foreach-construct.

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

Taking the input array equal to the unique names found in the first step, the trick is in the function to apply to each name. The function @(x) data(strcmp(tmp{1},x),:) first finds the indices for the the given name in tmp{1} (array containing all names) using strcmp. These indices are then used to index data = [tmp{2:end}], i.e., all the other arrays.

然后将每个唯一名称的结果存储在元胞数组 results 中.

The results for each individual unique name is then stored in the cell-array results.

使用结构

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

Using Structures

You can go one step further and use the cell-array results to have a more human-readable data structure. After applying all the previous steps, execute this:

for ii = 1:numel(names)
    output.(names{ii}) = results{ii}; end

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

Now you can reference to your data by name:

output.Name3(1,4)   %# to index the 4th '11' from 'Name3'

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

The syntax your_struct.('someString') is called dynamic structure referencing. It references or creates a field in the structure your_struc called someString.

现在,如果 names{ii} 包含你想去掉的下划线,那么你可以定义

Now, if names{ii} contains underscores you want to get rid of, then you can define

camelCase = @(x) regexprep(x, '_+(\w?)', '${upper($1)}')

camelCase = @(x) regexprep(x, ' +(\w?)', '${upper($1)}')

用于空格.然后使用

for ii = 1:numel(names)
    output.( camelCase(names{ii}) ) = results{ii}; end

感谢这些家伙 最后一个.

这篇关于Matlab将txt文件读入数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆