Python:numpy.genfromtxt - 需要包含无效字符的列名称

问题描述:

我正在导入带有numpy.genfromtxt的CSV文件。Python:numpy.genfromtxt - 需要包含无效字符的列名称

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

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

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

据我所知,deletechars存在,因为重新阵列可能访问字段,就好像它是一个属性。但是,我只需要能够读取包含无效字符的列名称,即使在读入时字符被剥离。

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

+1

难道你不能自己提取标题,然后跳过它来纯粹由'genfromtxt'提取数据吗? – 2012-08-07 06:32:22

+0

@JakobS。 - 我正在试验,阅读标题行,然后使用正则表达式来查找哪些名称包含无效字符并将其替换。然而,这对我来说并不是一个同质的解决方案,我希望numpy有一条规定可以绕过NameValidator或者至少重新定义删除者。 – freakinschweet 2012-08-07 06:48:18

+0

嗨,虽然我根据我对问题的最佳猜测给出了一个答案,但如果您给出了一个简化但完整的csv文件示例,它可能会有所帮助。 – xubuntix 2012-08-07 08:30:26

你没有明确说明numpy.genfromtxt是一个硬性要求,所以让我建议你试试asciitable

该模块的方式解析之前更换某些条目:http://cxc.harvard.edu/contrib/asciitable/#replace-bad-or-missing-values

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

ASCII表读取器的输出是numpy的阵列,所以你应该能够用asciitable直接替换你当前使用的函数。

NameValidator将使用其默认设置为deletechars如果构建与deletechars=None,但如果您通过非None设置然后它将使用它。并np.genfromtext需要deletechars参数,它传递到NameValidator

所以,你应该能够编写

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

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

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

恕我直言,genfromtxt通常在情况下,使用一些简单的解决方案会做。因此,除非你有一些麻烦的数据集(缺少条目,多个未知列类型),否则最好编写一个快速而脏的解析器(即,跳过一些行,解析头,读剩下的部分并重新组织结束)。

现在,如果你真的需要genfromtxt,@ecatmur理直气壮地指出那的genfromtxtdeletechars参数发送到_iotools.NameValidator来构建一套要删除的字符。使用deletechars=None告诉NameValidator使用默认设置。首先要尝试的是不使用deletechars=None,而是使用空的set''

需要注意的是不论怎样,双引号"和结束空间将被删除,类似的名称将有所区别:会导致命名blah分三路

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

第三和最后一个条目,所以我们要重命名它们。

如果这不适合你,我恐怕你打了一个块:目前没有办法告诉genfromtxt接受定制的NameValidator。不过,这可能是一个好主意,所以你可能想在numpy的邮件列表上提出点。

+0

这里有很多好处。 – freakinschweet 2012-08-07 13:39:45

+0

@xubuntix - 我会检查我的安装,看看是否可用。不幸的是,在我的工作环境中,添加新模块的过程非常困难。 @ecatmur @Pierre GM - 我也尝试过'genfromtxt'中的'deletechars = set()',但NameValidator类只是执行'set.extend(“”“〜!@#$%^&*() - =你可以想象,设置'deletechars ='''会产生一个ValueError,因为没有string.extend()。 ) 方法。此外,尝试修改'np.lib._iotools'将不起作用,因为'genfromtxt'会创建一个新实例。 谢谢大家的帮助! – freakinschweet 2012-08-07 13:51:12

+0

@ user1580983作为一种快速解决方案:使用'np.genfromtxt'代码创建自己的函数,然后摆脱'NameValidator'。这不会是可移植的,但会让你继续前进。我会建议在numpy邮件列表上发布这个问题,并最终打开一张票。 – 2012-08-07 14:08:57