Извлечение данных из .txt в Matlab - Испытанные importdata () - PullRequest
1 голос
/ 29 октября 2011

У меня есть .txt файлы, которые содержат вывод из регистратора данных.Данные регистрируются очень специфическим способом, с одним сообщением на строку и с идентификатором сообщения перед каждым сообщением.Итак, зная идентификатор сообщения каждой строки, я буду знать, что последует за этой строкой из-за формата сообщения.Каждое сообщение (другой идентификатор) имеет другой формат.Пример данных:

$GPGGA,220542.000,4745.8026,N,12211.0284,W,1,07,1.3,3.4,M,-17.2,M,,0000*67
$GPGSA,A,3,30,05,29,31,02,10,25,,,,,,2.0,1.3,1.5*3D
$GPGSV,3,1,12,29,78,315,39,05,52,080,45,30,43,288,46,25,41,196,33*72
$GPGSV,3,2,12,21,31,249,30,02,23,066,41,12,17,172,38,31,11,276,40*7F
$GPGSV,3,3,12,10,07,036,30,26,02,115,,18,01,199,,48,34,194,37*73
$GPRMC,220542.000,A,4745.8026,N,12211.0284,W,0.08,174.78,271011,,*12
$GPGGA,220543.000,4745.8025,N,12211.0284,W,1,07,1.3,3.4,M,-17.2,M,,0000*65

Все разделены запятыми, но поскольку каждая строка различна (то есть каждое сообщение не имеет одинаковый формат), я ничего не могу сделать с CSV (в Matlab).

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

Я могу поместить все в excel, используя csv, но, поскольку каждая строка отличается, трудно извлечь данные ... и я недаже знаю, возможно ли это в Excel (это, вероятно, так).

В Matlab я не могу использовать что-либо CSV, потому что есть нечисловые значения.Я попытался прочитать файл напрямую и захватить каждую строку с помощью fgetl (), а затем пройти по каждой строке, но должен быть более эффективный способ.Я прочитал кое-что о сохранении файла Excel, а затем перешел к matlab для извлечения данных, но было бы неплохо исключить этот промежуточный шаг.

Идеи о том, как это сделать, были бы хорошими.Я не ищу, чтобы кто-нибудь написал код для меня ... просто чтобы указать мне направление записи.

О, и я думал, что importdata () будет работать, но я попытался importdata ('filename.txt',', '), но он не распознает разделитель ...?

1 Ответ

1 голос
/ 29 октября 2011

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

Вот моя попытка прочитать файл, как вы его дали (вы не описали формат различных сообщений журнала, поэтому мне пришлось придумать свою собственную, основываясь на нескольких показанных строках).

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

Результатом будет массив ячеек с одной ячейкой для каждого сообщения.Я БЫ.Каждый из этих элементов будет сам по себе погребом, хранящим в виде таблицы прочитанные строки / столбцы.

%# line format for each type of message IDs
frmt = {
    '$GPGGA', '%s %f %f %c %f %c %f %f %f %f %c %f %c %f %s' ; 
    '$GPGSA', '%s %c %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %s' ; 
    '$GPGSV', '%s %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %s' ; 
    '$GPRMC', '%s %f %c %f %c %f %c %f %f %f %f %s' ; 
};

%# read log file as lines
fid = fopen('log.txt','rt');
C = textscan(fid, '%s', Inf, 'Delimiter','\n'); C = C{1};
fclose(fid);

%# get message ID of each line
msgId = strtok(C,',');

%# for each possible message ID
arr = cell(size(frmt,1),1);
for m=1:size(frmt,1)
    %# get lines matching this ID
    lines = C( ismember(msgId,frmt{m,1}) );

    %# parse lines using specified format
    arr{m} = cell(numel(lines), sum(frmt{m,2}=='%'));
    for i=1:numel(lines)
        arr{m}(i,:) = textscan(lines{i}, frmt{m,2}, 'Delimiter',',');
    end

    %# flatten nested cells containing strings
    idx = cellfun(@iscell, arr{m}(1,:));
    arr{m}(:,idx) = cellfun(@(x)x, arr{m}(:,idx));
end

log.txt

$GPGGA,220542.000,4745.8026,N,12211.0284,W,1,07,1.3,3.4,M,-17.2,M,,0000*67
$GPGSA,A,3,30,05,29,31,02,10,25,,,,,,2.0,1.3,1.5*3D
$GPGSV,3,1,12,29,78,315,39,05,52,080,45,30,43,288,46,25,41,196,33*72
$GPGSV,3,2,12,21,31,249,30,02,23,066,41,12,17,172,38,31,11,276,40*7F
$GPGSV,3,3,12,10,07,036,30,26,02,115,,18,01,199,,48,34,194,37*73
$GPRMC,220542.000,A,4745.8026,N,12211.0284,W,0.08,174.78,271011,,*12
$GPGGA,220543.000,4745.8025,N,12211.0284,W,1,07,1.3,3.4,M,-17.2,M,,0000*65

Результат для вышеуказанного файла:

>> arr
arr = 
    {2x15 cell}
    {1x18 cell}
    {3x20 cell}
    {1x12 cell}

например, строки, соответствующие messageID = $GPGGA:

>> arr{ ismember(frmt(:,1),'$GPGGA') }     %# arr{1}
ans = 
    '$GPGGA'    [220542]    [4745.8]    'N'    [12211]    'W'    [1]    [7]    [1.3]    [3.4]    'M'    [-17.2]    'M'    [NaN]    '0000*67'
    '$GPGGA'    [220543]    [4745.8]    'N'    [12211]    'W'    [1]    [7]    [1.3]    [3.4]    'M'    [-17.2]    'M'    [NaN]    '0000*65'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...