Как разобрать файл CSV с пустыми значениями в Octave? - PullRequest
0 голосов
/ 16 января 2020

У меня есть следующие данные CSV, которые я пытаюсь проанализировать в Octave. Обратите внимание, что значения в последнем столбце пусты:

102,19700101,,0.485,
111,19700101,,0.48,

Я определил свой формат строки как:

lineFormat = [repmat('%s',1,1), ...
         repmat('%f',1,1), ...
         repmat('%q',1,1), ...
         repmat('%f',1,1), ...
         repmat('%q',1,1)];

Как я могу прочитать это с помощью textscan? Когда я пытаюсь:

C = textscan(fid, lineFormat, 'Delimiter', ',')

Я неправильно получаю следующее (обратите внимание, что вторая строка из CSV смещена):

C = 
{
  [1,1] = 
  {
    [1,1] = 102
    [2,1] = 19700101
  }
  [1,2] =

     1.9700e+07
            NaN

  [1,3] = 
  {
    [1,1] = 
    [2,1] = 0.48
  }
  [1,4] =

       0.48500
     110.00000

  [1,5] = 
  {
    [1,1] = 111
    [2,1] = 19700101
  }
}

Я также пытался с 'MultipleDelimsAsOne', но последнее значение столбца все еще опущено. Как правильно прочитать мои данные CSV с помощью textscan? Этот код работает должным образом в MATLAB, но не в Octave.

Запуск Octave 4.2.2 в Ubuntu 16.04.

Ответы [ 2 ]

1 голос
/ 16 января 2020

Для вашего примера, мне помог параметр EndOfLine (Windows 10, Octave 5.1.0):

C = textscan(fid, lineFormat, 'Delimiter', ',', 'EndOfLine', '\n')

Вывод кажется правильным:

C =
{
  [1,1] =
  {
    [1,1] = 102
    [2,1] = 111
  }
  [1,2] =
     19700101
     19700101
  [1,3] =
  {
    [1,1] =
    [2,1] =
  }
  [1,4] =
     0.48500
     0.48000
  [1,5] =
  {
    [1,1] =
    [2,1] =
  }
}

Теперь я хотел протестировать ваши %q столбцы и расширил ваш пример:

102,19700101,,0.485,
111,19700101,,0.48,
111,19700101,,0.48,"test"
111,19700101,"test",0.48,

К сожалению, приведенное выше решение не работает должным образом:

C =
{
  [1,1] =
  {
    [1,1] = 102
    [2,1] = 111
    [3,1] = 111
    [4,1] =
  }
  [1,2] =

     19700101
     19700101
     19700101
          111
  [1,3] =
  {
    [1,1] =
    [2,1] =
    [3,1] =
    [4,1] = 19700101
  }
  [1,4] =

     0.48500
     0.48000
     0.48000
  [1,5] =
  {
    [1,1] =
    [2,1] =
    [3,1] = test
  }
}

Но при переключении с %q на %s в lineformat все работает как положено:

C =
{
  [1,1] =
  {
    [1,1] = 102
    [2,1] = 111
    [3,1] = 111
    [4,1] = 111
  }
  [1,2] =

     19700101
     19700101
     19700101
     19700101
  [1,3] =
  {
    [1,1] =
    [2,1] =
    [3,1] =
    [4,1] = "test"
  }
  [1,4] =
     0.48500
     0.48000
     0.48000
     0.48000
  [1,5] =
  {
    [1,1] =
    [2,1] =
    [3,1] = "test"
    [4,1] =
  }
}

У меня нет объяснения этому; ошибка может быть? Если после этого вы сможете сами избавиться от двойных кавычек, это (все же) может помочь вам.

Надеюсь, это поможет!

0 голосов
/ 22 января 2020

Похоже, что это ошибка в октаве: https://savannah.gnu.org/bugs/index.php?57612

Я справился с этим, добавив дополнительную запятую в конец моих файлов CSV, строки которых заканчивались запятой. Поскольку Octave игнорирует последнюю запятую, добавление второй запятой приводит к тому, что Octave не игнорирует предпоследнюю:

102,19700101,,0.485,,
111,19700101,,0.48,,

Вот одна строчка оболочки для исправления всех файлов CSV в каталоге:

find ${1:-.} -type f -name *.csv -exec sed -i -e 's/,$/,,/g' {} \;

Это не отличное решение, просто обход существующей ошибки.

...