需要阅读一个充满奇怪格式数据的巨大文本文件。格式如下:
//Header with Title Info
//Header with Test1 Info
//More Test1 Info
0,-156.875956035285
1.953125,-4.82866496038806
3.90625,-8.93502887648155
5.859375,-9.76964479822559
7.8125,-14.9767168331976
9.765625,-16.9949034672061
11.71875,-19.2709033739316
13.671875,-18.9948581866681
//Header with Test2 Info
//More Test2 Info
0,-156.875956035285
1.953125,-4.82866496038806
3.90625,-8.93502887648155
5.859375,-9.76964479822559
7.8125,-14.9767168331976
9.765625,-16.9949034672061
11.71875,-19.2709033739316
13.671875,-18.9948581866681
//Header with Test3 Info
//More Test3 Info
0,-156.875956035285
1.953125,-4.82866496038806
3.90625,-8.93502887648155
5.859375,-9.76964479822559
7.8125,-14.9767168331976
9.765625,-16.9949034672061
11.71875,-19.2709033739316
13.671875,-18.9948581866681
// End of Data
这是它的要点,除了每个标题下有大约25,000个条目而不是8个。我运行25个测试,需要将它们一起平均为一组数据。
基本上,我想解析这个序列中的数据:
然后,我想以最有效的方式将所有这些集合平均化。
我在阅读数据时遇到了问题。我知道我可以使用csvread,或者更通用的函数来读取分隔值,但是我很难找到一种优雅而简洁的方法来完成所有事情。
我从这开始:
function [ data ] = graph( input_args )
%Plot data
myData = fopen('mRoom_fSweep_25points_center.txt');
data = textscan(myData,'%s');
fclose(myData);
length(data)
end
我想我可以找到这个字符串数组的长度,并为整个操作列表设计一个for循环,但我无法超越这一点:输出一直给我这个:
ans =
{772321x1 cell}
我无法使用。当我尝试将它存储在一个变量中时,它给出的值为1.我在这里找不到像单元数组一样奇怪的东西吗?
答案 0 :(得分:4)
我假设您需要“测试信息”行中的信息?
如果是这样,您需要使用两种不同的模式运行textscan
:一种用于选择信息行,另一种用于读取数据:
info(1, end+1) = textscan(fid, '//%s','Delimiter', '');
data(1, end+1) = textscan(fid, '%f, %f', 'CollectOutput', true);
下面是我如何用循环和错误处理来包装它:
% [info, data] = read_data(file_name): Read a file in funky format
%
% info and data are cells of same size
function [info, data] = read_data(file_name)
[fid, msg] = fopen(file_name);
if fid<0
error('Unable to open file "%s": %s', file_name, msg);
end
% close the file no matter how we exit this funciton (error,
% ctrl-c,...)
finalize = onCleanup(@() fclose(fid));
info = cell(1,0);
data = cell(1,0);
while true
info(1, end+1) = textscan(fid, '//%s','Delimiter', '');
data(1, end+1) = textscan(fid, '%f, %f', 'CollectOutput', true);
if strcmpi(info{1,end}{end}, 'End of Data')
% End of data reached, exit here
info = info(1:end-1);
data = data(1:end-1);
break;
end
if isempty(data{1,end})
% Empty data, but not 'End of data' marker.
% Replace this error with break to accept files with missing
% "end of data" tags
error('Empty data before "End of Data" line')
end
end
end
然后,您可以按如下方式读取文件并计算平均值:
>> [info, data] = read_data('foo.txt')
info =
{3x1 cell} {2x1 cell} {2x1 cell}
data =
[8x2 double] [8x2 double] [8x2 double]
>> info{3}
ans =
'Header with Test3 Info'
'More Test3 Info'
>> all_data = cellfun(@(d) d(:,2), data, 'UniformOutput', false); all_data = [all_data{:}]
all_data =
-156.8760 -156.8760 -156.8760
-4.8287 -4.8287 -4.8287
-8.9350 -8.9350 -8.9350
-9.7696 -9.7696 -9.7696
-14.9767 -14.9767 -14.9767
-16.9949 -16.9949 -16.9949
-19.2709 -19.2709 -19.2709
-18.9949 -18.9949 -18.9949
>> mean(all_data, 2)
ans =
-156.8760
-4.8287
-8.9350
-9.7696
-14.9767
-16.9949
-19.2709
-18.9949