Pandas HDF5选择非自然命名列的Where条件查询

3
在我持续的熊猫/HDF5问题冒险中,我遇到了以下问题:
我有一系列非自然命名的列(注:因为有好的原因,负数为“系统”标识符等),通常不会出现问题:
fact_hdf.select('store_0_0', columns=['o', 'a-6', 'm-13'])

然而,我的选择语句却失败了:
>>> fact_hdf.select('store_0_0', columns=['o', 'a-6', 'm-13'], where=[('a-6', '=', [0, 25, 28])])
blablabla
File "/srv/www/li/venv/local/lib/python2.7/site-packages/tables/table.py", line 1251, in _required_expr_vars
    raise NameError("name ``%s`` is not defined" % var)
NameError: name ``a`` is not defined

有没有什么办法可以解决这个问题?我可以将我的负值从"a-1"重命名为"a_1",但这意味着需要重新加载我系统中的所有数据。这还是比较麻烦的!:)
欢迎提出建议!
1个回答

3
这是一个测试表格。
In [1]: df = DataFrame({ 'a-6' : [1,2,3,np.nan] })

In [2]: df
Out[2]: 
   a-6
0    1
1    2
2    3
3  NaN

In [3]: df.to_hdf('test.h5','df',mode='w',table=True)

 In [5]: df.to_hdf('test.h5','df',mode='w',table=True,data_columns=True)
/usr/local/lib/python2.7/site-packages/tables/path.py:99: NaturalNameWarning: object name is not a valid Python identifier: 'a-6'; it does not match the pattern ``^[a-zA-Z_][a-zA-Z0-9_]*$``; you will not be able to use natural naming to access this object; using ``getattr()`` will still work, though
  NaturalNameWarning)
/usr/local/lib/python2.7/site-packages/tables/path.py:99: NaturalNameWarning: object name is not a valid Python identifier: 'a-6_kind'; it does not match the pattern ``^[a-zA-Z_][a-zA-Z0-9_]*$``; you will not be able to use natural naming to access this object; using ``getattr()`` will still work, though
  NaturalNameWarning)
/usr/local/lib/python2.7/site-packages/tables/path.py:99: NaturalNameWarning: object name is not a valid Python identifier: 'a-6_dtype'; it does not match the pattern ``^[a-zA-Z_][a-zA-Z0-9_]*$``; you will not be able to use natural naming to access this object; using ``getattr()`` will still work, though
  NaturalNameWarning)

有一种方法,可以将其构建到代码本身中。您可以按以下方式对列名进行变量替换。这是现有例程(在主分支中)

   def select(self):
        """
        generate the selection
        """
        if self.condition is not None:
            return self.table.table.readWhere(self.condition.format(), start=self.start, stop=self.stop)
        elif self.coordinates is not None:
            return self.table.table.readCoordinates(self.coordinates)
        return self.table.table.read(start=self.start, stop=self.stop)

如果你这样做的话
(Pdb) self.table.table.readWhere("(x>2.0)",
      condvars={ 'x' : getattr(self.table.table.cols,'a-6')})
array([(2, 3.0)], 
      dtype=[('index', '<i8'), ('a-6', '<f8')])

例如,通过用列引用替换x,您可以获取数据。

这可以在检测到无效列名时完成,但相当棘手。

不幸的是,我建议重新命名您的列。


再次感谢Jeff!我想知道它在0.10/0.11和0.12之间是否有变化,但我猜随着即将到来的0.13新where子句,这也无关紧要了 :) 不过,对于新用户,将其作为警告放入pandas HDF5文档可能是个好主意?虽然pandas本身并没有问题,正常的数据检索也能工作,但直到遇到select语句问题才会显得不太明显... - Carst
好的...我会这样做。Pandas 版本并不是很重要(虽然在0.13版本中,where子句的语法更加灵活,因此实际上很难弄清楚),请参见这里 - Jeff

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接