【问题标题】:How to parse CSV file with empty values in Octave?如何在 Octave 中解析具有空值的 CSV 文件?
【发布时间】:2020-01-16 01:04:25
【问题描述】:

我尝试在 Octave 中解析以下 CSV 数据。注意最后一列的值为空:

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',但最后一列的值仍然被省略。如何使用textscan 正确读取我的 CSV 数据?此代码在 MATLAB 中按预期工作,但在 Octave 中不正常。

在 Ubuntu 16.04 上运行 Octave 4.2.2。

【问题讨论】:

  • 使用csv2cell 包中的csv2cell 函数。它比通用的 csvread 函数有用得多。话虽如此,在这种情况下,您也可以轻松使用标准的 csvread,根本不需要复杂的 textscan ...
  • @TasosPapastylianou 我相信我需要textscan,因为最后一列中的值可以是字符串。不过,我会调查csv2cell
  • 是的,做。 csv2cell 可以处理任何内容,并且与 textscan 等相比更轻松。值得牢记。 (顺便说一句,我喜欢你的个人资料照片!)

标签: matlab csv octave


【解决方案1】:

对于您的示例,设置 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
  }
}

但是,当在lineformat 中从%q 切换到%s 时,它会按预期工作:

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] =
  }
}

我对此没有任何解释;也许是一个错误?如果您以后可以自己删除双引号,那么这(仍然)可能是您的解决方案。

希望有帮助!

【讨论】:

  • 感谢您的帮助。不幸的是,这并没有解决我的问题。我在 Ubuntu 16.04 上运行 Octave 4.2.2,将该信息添加到问题中。暂时起作用的是在 CSV 的最后一列中添加一个空格字符,使其不为空,但这不是一个很好的解决方案。
  • 我也打开了这个bug:savannah.gnu.org/bugs/index.php?57612
【解决方案2】:

这似乎是 Octave 中的一个错误:https://savannah.gnu.org/bugs/index.php?57612

我通过在 CSV 文件的末尾添加一个额外的逗号来解决这个问题,该文件的行以逗号结尾。由于 Octave 会忽略最后一个逗号,因此添加第二个逗号会导致 Octave 不会忽略倒数第二个:

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

这是一个用于修复目录中所有 CSV 文件的 shell 单行代码:

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

这不是一个很好的解决方案,只是现有错误的解决方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-29
    相关资源
    最近更新 更多