Чтение данных с использованием textscan в MATLAB

Мне нужно прочитать следующие данные из текстового файла в MATLAB. Это всего лишь пример, фактическая матрица содержит данные от 1218 станций (USH обозначает США, а число рядом с этим номером является идентификатором станции), каждый столбец представляет собой месячное значение. Значения столбца номер 2 являются флагами, которые мне не нужны в окончательной форме данных. Как мне поступить?

USH00011084 1890 -9999    -9999    -9999    -9999    -9999    -9999    -9999    -9999    -9999    -9999    -9999      170  2 -9999   
USH00011084 1891   550  2   561  2   575  2   165  2   275  2   670  2   425  2   172  2   200  2     0  2   930  2   525  2  5048   
USH00011084 1892  1245  2   440  2   256  2   160  2   380  2   780  2  1226  2  1355  2   300  2   100  2   165  2 -9999    -9999   
USH00011084 1893   535  2   608  2   465  2   380  2   730  2   345  2   425  2   645  2   345  2   635  2   487  2   487  2  6087   
USH00011084 1894   240  2  1649  2   788  2   225  2   465  2   265  2 -9999    -9999    -9999       30  2 -9999       75  2 -9999   
USH00011084 1895 -9999      150  2   400  2   400  2   400  2   400  2   300  2 -9999    -9999      200  2 -9999      300  2 -9999   
USH00011084 1896   440  2  1340  2   590  2 -9999      320  2  1100  2   935  2   185  2   140  2   500  2   340  2   225  2 -9999   
USH00011084 1897   245  2  1230  2   475  2   435  2    50  2    25  4   735  2   980  2     0  2     0  2 -9999    -9999    -9999   
USH00011084 1900 -9999    -9999      731  2   704  2   225  2  1296  2   783  2   391  2   611  2   648  2   192  2   607  2 -9999   
USH00011084 1926 -9999      553     1031      356      503      678      846a    1161     1369      348      324      354    -9999   
USH00011084 1927    99      920      501       89      225      731      444      703      437      316      560      937     5963   
USH00011084 1928   111a     804      730     1409      351      779      535      607    -9999    -9999    -9999    -9999    -9999   

person user962808    schedule 24.03.2015    source источник
comment
Должно ли быть значение 846a и 111a в последней строке?   -  person horchler    schedule 24.03.2015
comment
Нет, мне нужно читать числа 846 и 111 вместо того, чтобы читать их как 111а и 846а. Мне нужно прочитать целую часть, а не строку. Да, в сыром виде они присутствуют в данных.   -  person user962808    schedule 24.03.2015
comment
Эти данные плохо отформатированы для легкого и надежного чтения. Он разделен пробелами, но во многих строках отсутствуют значения. Каково значение значений 2, которые присутствуют в одних случаях, но отсутствуют в других (и всегда ли они равны 2)? Нужно ли также считывать значения 2?   -  person horchler    schedule 24.03.2015


Ответы (2)


Похоже, что ваши данные имеют отформатированную ширину столбца, поэтому вы можете уйти с чем-то вроде этого:

data = fileread('data.txt')';
data = strvcat(strsplit(data,char(10),1));
data(:,25:9:end) = [];
data(:,23:8:end) = [];

stations = strtrim(mat2cell(data(:,1:12), ones(size(data,1),1),12))
data = str2num(data(:,13:end))

Это не принесет награды за элегантность, но будет последовательно выполнять работу, если столбцы всегда имеют одинаковую ширину, и должно работать, даже если количество столбцов изменяется. stations - это массив столбцов ячеек, а данные имеют тип double. Если вам нужно выбрать что-то еще, вы можете повозиться с выбором разделов, которые удаляются.

Для вашего примера данные представляют собой следующую матрицу:

data =

   1890  -9999  -9999  -9999  -9999  -9999  -9999  -9999  -9999  -9999  -9999  -9999    170  -9999
   1891    550    561    575    165    275    670    425    172    200      0    930    525   5048
   1892   1245    440    256    160    380    780   1226   1355    300    100    165  -9999  -9999
   1893    535    608    465    380    730    345    425    645    345    635    487    487   6087
   1894    240   1649    788    225    465    265  -9999  -9999  -9999     30  -9999     75  -9999
   1895  -9999    150    400    400    400    400    300  -9999  -9999    200  -9999    300  -9999
   1896    440   1340    590  -9999    320   1100    935    185    140    500    340    225  -9999
   1897    245   1230    475    435     50     25    735    980      0      0  -9999  -9999  -9999
   1900  -9999  -9999    731    704    225   1296    783    391    611    648    192    607  -9999
   1926  -9999    553   1031    356    503    678    846   1161   1369    348    324    354  -9999
   1927     99    920    501     89    225    731    444    703    437    316    560    937   5963
   1928    111    804    730   1409    351    779    535    607  -9999  -9999  -9999  -9999  -9999
person Buck Thorn    schedule 24.03.2015

% open the file
fid = fopen('C:\temp\foo.txt');
if ~fid
    error('Unable to open file');
end

% define column formats
colFormats{1} = '%11s';
colFormats{2} = '%4s';
colFormats{3} = '%5s';
colFormats{4} = '%1s';
colFormats{5} = '%5s';
colFormats{6} = '%1s';
colFormats{7} = '%5s';
colFormats{8} = '%1s';
colFormats{9} = '%5s';
colFormats{10} = '%1s';
colFormats{11} = '%5s';
colFormats{12} = '%1s';
colFormats{13} = '%5s';
colFormats{14} = '%1s';
colFormats{15} = '%5s';
colFormats{16} = '%1s';
colFormats{17} = '%5s';
colFormats{18} = '%1s';
colFormats{19} = '%5s';
colFormats{20} = '%1s';
colFormats{21} = '%5s';
colFormats{22} = '%1s';
colFormats{23} = '%5s';
colFormats{24} = '%1s';
colFormats{25} = '%5s';
colFormats{26} = '%1s';
colFormats{27} = '%5s';

% read data
data = textscan(fid, cell2mat(colFormats),'MultipleDelimsAsOne',true);

% close file
fclose(fid);

% extract numbers from col 3...

cellfun(@(x) str2double(x(~isletter(x))), data{3}, 'uniformoutput', false)

ответ =

[-9999]
[  550]
[ 1245]
[  535]
[  240]
[-9999]
[  440]
[  245]
[-9999]
[-9999]
[   99]
[  111]
person siliconwafer    schedule 24.03.2015