【问题标题】:Python: numpy.genfromtxt - Need column names that contain invalid charactersPython:numpy.genfromtxt - 需要包含无效字符的列名
【发布时间】:2012-08-07 06:20:21
【问题描述】:

我正在使用 numpy.genfromtxt 导入 CSV 文件。

要导入的数据有一个列名标题,其中一些列名包含genfromtxt 认为无效的字符。具体来说,一些名称包含“#”和“”。输入数据无法更改,因为它是由我无法控制的其他来源生成的。

使用names=Truecomments=None,我无法引入我需要的所有列名。

我尝试过覆盖numpy.lib.NameValidator.deletechars=None,但这不会影响实际使用的 NameValidator 类实例。

我知道deletechars 的存在是因为recarray 可能会像访问属性一样访问字段。但是,我必须能够读入包含无效字符的列名,即使在读入时这些字符被剥离。

有没有办法强制NameValidator 不检查无效字符,或者修改它检查的字符?我无法修改 numpy/lib/_iotools.py,因为我不是 root,修改共享安装会很糟糕。

【问题讨论】:

  • 你不能自己提取标题然后跳过它以通过genfromtxt进行纯数据提取吗?
  • @JakobS。 - 我目前正在试验,阅读标题行,然后使用正则表达式查找哪些名称包含无效字符并替换它们。但是,这对我来说并不是一个同质的解决方案,我希望 numpy 能够绕过 NameValidator 或至少重新定义 deletechars。
  • 您好,虽然我已经根据我对问题的最佳猜测给出了答案,但如果您提供一个简化但完整的 csv 文件示例,可能会有所帮助。

标签: python numpy genfromtxt


【解决方案1】:

您没有明确声明 numpy.genfromtxt 是硬性要求,所以我建议您尝试asciitable

这个模块可以在解析前替换某些条目:http://cxc.harvard.edu/contrib/asciitable/#replace-bad-or-missing-values

您还可以根据现有读者定义自己的读者:http://cxc.harvard.edu/contrib/asciitable/#advanced-table-reading

asciitable reader 的输出是 numpy 数组,所以你应该可以直接用 asciitable 或多或少地替换你当前使用的函数。

【讨论】:

    【解决方案2】:

    NameValidator 将使用deletechars 的默认设置,如果使用deletechars=None 构造,但如果您传入非None 设置,那么它将使用它。而np.genfromtext 接受一个deletechars 参数,并将其传递给NameValidator

    所以,你应该会写

    np.genfromtxt(..., deletechars=set())
    

    对于一个空集,或者默认set("""~!@#$%^&*()-=+~\|]}[{';: /?.>,<""")的某个子集:

    deletechars = np.lib._iotools.NameValidator.defaultdeletechars - set("# ")
    np.genfromtxt(..., deletechars=deletechars)
    

    【讨论】:

      【解决方案3】:

      恕我直言,genfromtxt 通常用于一些更简单的解决方案可以做到的情况。

      因此,除非您有一些麻烦的数据集(缺少条目、多个未知的列类型),否则最好编写一个快速而肮脏的解析器(即跳过一些行、解析标题、读取其余部分并在结束)。

      现在,如果你真的需要genfromtxt,@ecatmur 公正地指出genfromtxtdeletechars 参数被发送到_iotools.NameValidator 以构造要删除的字符集。使用deletechars=None 告诉NameValidator 使用默认设置。首先要尝试的是不要使用deletechars=None,而是使用空的set''

      注意不管怎样,双引号"和结尾的空格都会被删除,类似的名字会被区分:

      >>> fields = ["blah", "'blah'", "\"blah\"", "#blah", "blah "]
      >>> np.lib._iotools.NameValidator(deletechars='').validate(fields)
      ... ('blah', "'blah'", 'blah_1', '#blah', 'blah_2')
      

      第三个和最后一个条目将产生三个名为 blah 的列,因此我们必须重命名它们。

      如果这不适合你,恐怕你会遇到障碍:目前没有办法告诉genfromtxt 接受定制的NameValidator。不过,这可能是个好主意,因此您可能想在 numpy 的邮件列表中提出这一点。

      【讨论】:

      • @xubuntix - 我将检查我的安装以查看 asciitable 是否可用。不幸的是,在我的工作环境中,添加新模块的过程非常困难。 @ecatmur @Pierre GM - 我也在genfromtxt 中尝试过deletechars=set(),但NameValidator 类只是使用传入的任何内容执行set.extend("""~!@#$%^&*()-=+~\|]}[{';: /?.>,<""")。您可以想象,设置deletechars='' 会由于没有字符串而引发ValueError。扩展()方法。此外,尝试修改np.lib._iotools 将不起作用,因为genfromtxt 创建了一个新实例。谢谢大家的帮助!
      • @user1580983 作为一个快速的解决方案:使用np.genfromtxt 的代码创建自己的函数并摆脱NameValidator。这不会是便携式的,但会让你继续前进。我建议在 numpy 邮件列表上发布有关此问题的信息,并最终打开一张票。
      猜你喜欢
      • 2014-12-04
      • 2017-11-16
      • 1970-01-01
      • 2020-02-04
      • 2018-06-04
      • 2017-03-18
      • 2020-02-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多