Надежное чтение файла табличных данных с помощью Matlab

Я пытаюсь получить доступ к числовым данным в текстовом файле, созданном измерительным устройством. Файлы представляют собой смесь строк и чисел, а элементы разделены табуляцией. Он не прямоугольный, что делает его непригодным для функций загрузки файлов Matlab, таких как dlmread. Я могу преобразовать файлы в электронные таблицы exel и загрузить их с помощью xlsread, но, поскольку я имею дело с сотнями файлов, это не вариант для меня.

Вот как выглядят файлы:

Heading String  
Commenttext 
X Axis  Trace A Trace B 
Frequency   Funct Ch1   Funct Ch2   
Frequency / Hz  Funct Ch1 / dBr Funct Ch2 / dBV 
Hz  dBr dBV 
LOG LIN LIN 
100 -60.35  -71.1446    
10000   -7.48178    -12.0321    
VOID    VOID    VOID    
VOID    VOID    VOID    
Scan #-5    Labeltext   Labeltext   
Hz  V   V   
1.000000000000e+003 3.999999910593e-002 1.000000000000e+000 
A-X/37   A-Y     A-LimLow    A-LimUpp   A-RefY in V     B-X/37   B-Y    B-LimLow    B-LimUpp    B-RefY in V     
1.000000000000e+002 -4.873095199691e+001    VOID    VOID    3.999999910593e-002 1.000000000000e+002 -2.026775796775e+001    VOID    VOID    1.000000000000e+000 
1.172102297533e+002 -4.492478734843e+001    VOID    VOID    3.999999910593e-002 1.172102297533e+002 -2.024411835772e+001    VOID    VOID    1.000000000000e+000 
1.373823795883e+002 -3.994765661259e+001    VOID    VOID    3.999999910593e-002 1.373823795883e+002 -2.022767912575e+001    VOID    VOID    1.000000000000e+000 
1.610262027561e+002 -3.628116388971e+001    VOID    VOID    3.999999910593e-002 1.610262027561e+002 -2.021939551014e+001    VOID    VOID    1.000000000000e+000 
1.887391822135e+002 -3.285059881019e+001    VOID    VOID    3.999999910593e-002 1.887391822135e+002 -2.021928320409e+001    VOID    VOID    1.000000000000e+000 
2.212216291070e+002 -2.987476652701e+001    VOID    VOID    3.999999910593e-002 2.212216291070e+002 -2.022570411546e+001    VOID    VOID    1.000000000000e+000 
2.500000000000e+002 -2.751190343935e+001    VOID    VOID    3.999999910593e-002 2.500000000000e+002 -2.023346726318e+001    VOID    VOID    1.000000000000e+000 
2.592943797405e+002 -2.728162367715e+001    VOID    VOID    3.999999910593e-002 2.592943797405e+002 -2.023601503648e+001    VOID    VOID    1.000000000000e+000

и т.п.

Обратите внимание, что: - Значение перед сканом #-5 говорит мне, сколько повторений есть в файле - A-X/37 сообщает мне, сколько строк в скане есть. - Элементы VOID заменяются фактическими числами, когда это применимо, и наоборот.

Я хотел бы иметь возможность извлекать имеющиеся значения и чтобы мой сценарий не зависел от размера трасс, количества повторений или от того, являются ли значения числами или «ПУСТОТАМИ».

До сих пор, основываясь на советах, данных в других ветвях, я смог создать массив со строками файла и извлечь 2 первых числа каждой строки следующим образом:

fid=fopen('data.txt');
Rows = textscan(fid,'%s', 'delimiter','\n'); %Creates a temporary array with the rows of the file
fclose(fid);
TraceStarts=strfind(Rows{1,1},'Scan'); %Looks for the start of each trace..
TracesIdx = find(~cellfun('isempty', TraceStarts)); %.. and stores the indexes.
Traces= cellfun(@(x) textscan(x,'%f','delimiter','\t', 'CollectOutput',1), Rows{1,1});

Затем Traces представляет собой ячейку, содержащую массивы для каждой строки с максимум двумя первыми числами в строке. Почему он прекращает поиск элементов с плавающей запятой в строке после того, как нашел 2, для меня загадка... Я не хочу указывать последовательность чисел и строк в каждой строке, потому что они могут различаться.

Любая помощь приветствуется.


person Cape Code    schedule 30.09.2013    source источник
comment
Не хотел бы downvoter прокомментировать?   -  person Cape Code    schedule 17.08.2015


Ответы (1)


Ваш textscan сообщает только о двух элементах из-за VOID элементов. Просто скажите textscan рассматривать их как «пустые», чтобы они читались как NaN. См. пару "имя-значение" TreatAsEmpty в документации textscan.

>> str = '1.000000000000e+002 -4.873095199691e+001    VOID    VOID    3.999999910593e-002 1.000000000000e+002 -2.026775796775e+001    VOID    VOID    1.000000000000e+000';
>> textscan(str,'%f','delimiter','\t', 'CollectOutput',1)
ans = 
    [2x1 double]
>> textscan(str,'%f','delimiter','\t', 'CollectOutput',1,'treatAsEmpty',{'VOID'})
ans = 
     [10x1 double]
>> ans{1}
ans =
                       100
           -48.73095199691
                       NaN
                       NaN
          0.03999999910593
                       100
           -20.26775796775
                       NaN
                       NaN
                         1
person mbauman    schedule 30.09.2013