在Matlab中读取复杂的长文本文件

时间:2017-06-10 09:03:12

标签: matlab text text-files

我有一个很长的文本文件,其中包含来自4个不同时间步的不同站的数据:

1:00
station 1
a number 1  (e.g.0.6E-06)
matrix1 (41x36)
station 2
number 2    (e.g.0.1E-06)
matrix2 (41x36)
station 3
number 3   (e.g.0.2E-06)
matrix3 (41x36)
station 4
number 4    (e.g.0.4E-06)
matrix4 (41x36)

2:00
station 1
a number   (e.g.0.24E-06)
matrix5 (41x36)
station 2
a number     (e.g.0.3E-06)
matrix6 (41x36)
station 3
number     (e.g.0.12E-06)
matrix7 (41x36)
station 4
number     (e.g.0.14E-06)
matrix8 (41x36)

..... 等等

我需要通过每个站和每个步骤读取这些数据,并注意每个矩阵应该通过乘以它上面的数字来缩放。这里有一个例子:https://files.fm/u/sn447ttc#/view/example.txt

你可以帮忙吗?

非常感谢你。

2 个答案:

答案 0 :(得分:0)

我的想法是使用fopentextscan阅读文本文件。之后,您可以搜索关键字FACTOR的外观以细分输出。这是代码:

fid=fopen('example.txt'); % open the document
dataRaw=textscan(fid,'%s','Delimiter',''); % read the file with no delimiter to achieve a cell array with 1 cell per line of the text file
fclose(fid); % close the document
rows=cellfun(@(x) strfind(x,'FACTOR'),dataRaw,'uni',0); % search for appearances of 'FACTOR'
hasFactor=find(~cellfun(@isempty,rows{1})); % get rownumbers of the lines that contain the word FACTOR
dataRaw=dataRaw{1}; % convert array for easier indexing
for ii=1:(numel(hasFactor)-1) % loop over appearances of the word FACTOR
    array=cellfun(@str2num,dataRaw(hasFactor(ii)+2:hasFactor(ii+1)-1),'uni',0); % extract numerical data
    output{ii}=str2num(dataRaw{hasFactor(ii)+1})*cat(1,array{:}); % create output scaled by the factor
end
array=cellfun(@str2num,dataRaw(hasFactor(end)+2:end),'uni',0);
output{end+1}=str2num(dataRaw{hasFactor(end)+1})*cat(1,array{:}); % These last 2 lines add the last array to the ouput
outputMat=cat(3,output{:}); % convert to a 3-dimensional matrix
outputStations=[{output(1:4:end)} {output(2:4:end)} {output(3:4:end)} {output(4:4:end)}]; % Sort the output to have 1 cell for each station
outputColumnSums=cellfun(@(x) cellfun(@sum,x,'uni',0),outputStations,'uni',0); % To sum up all the columns of each matrix
outputRowSums=cellfun(@(x) cellfun(@(y) sum(y,2),x,'uni',0),outputStations,'uni',0);

这种方法非常缓慢,可能是矢量化的,但如果你不需要快速的话,就应该做好工作。我创建了一个单元格输出,每个数组1个单元格,3个数组作为可选输出。希望你这么好

答案 1 :(得分:0)

我已经调查了你的情况,似乎问题不是如预期的那样微不足道。请记住,如果我在假设数据位置时犯了错误,您可以让我知道,以便我可以编辑它,或者您只需将数字更改为适合您的情况。在这种情况下,我最初将分隔文件加载到Excel电子表格中,只是为了将其可视化。

在阅读dlmread之后,我发现可以指定从example.txt提取的确切行和列,如下所示:

data = dlmread('example.txt', ' ', [4 1 45 37]); % [r1 c1 r2 c2]
data2 = dlmread('example.txt', ' ', [47 1 88 37]);

其结果是两个矩阵41-by-37,仅包含数字。我在第4行开始data以绕过标题信息/字符串。注意到模式,我将其设置为循环:

No_of_matrices_expected = 4;
dataCell = cell(No_of_matrices_expected, 1);
iterations = length(dataCell)

% Initial Conditions
rowBeginning = 4;
col1 = 1; % Constant
rowEnd = rowBeginning + 40; % == 44, right before next header information
col2 = 36; % Constant

for n = 1 : iterations
    dataCell{n} = dlmread('example.txt', ' ', [rowBeginning, col1, rowEnd, col2]);
    rowBeginning = rowBeginning + 41 + 2; % skip previous matrix and skip header info
    rowEnd = rowBeginning + 40;
end

然而,我偶然发现你之前说过的是有四个不同的电台,每个电台都有自己的时间戳。因此,运行此循环超过4次会导致意外结果并且MATLAB崩溃。原因是新时间戳为日期创建了一个额外的行。现在,您可以更改上面的循环以补偿这个额外的行,或者您可以为每个站点创建多个for循环。这将是您的决定。

现在,如果您想保存标题信息,我建议您查看textscan。您可以简单地使用此函数将所有数据的第一列拉入字符串的单元格数组中。然后,您可以提取所需的标题信息。请注意,如果您想使用textscan,请使用fopen

我会让你使用我迄今为止找到的内容,但如果你需要更多的帮助,请告诉我。

编号