Python Pandas hdfstore 的 select(where='') 返回不合格的结果

Posted

技术标签:

【中文标题】Python Pandas hdfstore 的 select(where=\'\') 返回不合格的结果【英文标题】:Python Pandas hdfstore's select(where='') return unqualified resultsPython Pandas hdfstore 的 select(where='') 返回不合格的结果 【发布时间】:2015-08-27 22:44:25 【问题描述】:

当我像这样查询一个大的 hdfstore 文件 (>10G) 时:

hdf = pd.HDFStore('raw_sample_storage.h5')
nrows = hdf.get_storer('raw_sample_all').nrows
chunksize = 300000

for i in xrange(nrows//chunksize + 1):
    chunk = hdf.select('raw_sample_all', where=[pd.Term('node_id', '==', 1)], start=i*chunksize, stop=(i+1)*chunksize)
    print chunk.head(2)

我得到了大多数条目的 node_id 为 1 的结果,但有些条目的 node_id 不是 1。这是 hdfstore 故障,还是我做错了什么?

这是结果的一部分,您可以看到有一些 node_id 不是 1 的条目。

                 time   GW_time  node_id      X      Y      Z  status  seq  \
2 2013-10-22 17:20:58  39821888        1  16927  21438  22722       0   34   
6 2013-10-22 17:20:58  39822144        1  16927  21438  22722       0   35   

   rssi  lqi  
2   -46   48  
6   -51   48  
                      time   GW_time  node_id      X      Y      Z  status  \
300002 2013-10-22 17:30:50  59223744        3  19915  20840  22003       0   
300006 2013-10-22 17:30:50  59224000        3  19913  20844  22002       0   

        seq  rssi  lqi  
300002   46   -64   50  
300006   47   -64   48  
                      time   GW_time  node_id      X      Y      Z  status  \
600000 2013-10-22 17:40:55  79050561        1  17612  22536  21198       0   
600004 2013-10-22 17:40:55  79050817        1  17613  22535  21201       0   

        seq  rssi  lqi  
600000   55   -67   46  
600004   56   -67   49  
                      time   GW_time  node_id      X      Y      Z  status  \
900003 2013-10-22 17:50:44  98345217        4  18934  20212  19364       0   
900007 2013-10-22 17:50:44  98345473        4  18935  20212  19359       0   

        seq  rssi  lqi  
900003   32   -60   46  
900007   33   -60   48  
                       time    GW_time  node_id      X      Y      Z  status  \
1200003 2013-10-22 18:00:31  117600065        1  17618  22541  21191       0   
1200007 2013-10-22 18:00:31  117600321        1  17620  22538  21187       0   

         seq  rssi  lqi  
1200003  111   -66   47  
1200007  112   -66   48  

注意到第 300002 行是一个不需要的结果,我尝试在该特定区域周围选择节点 1,如下所示:

chunk = hdf.select('raw_sample_all', start=300002-20, stop=300002+20, 
                       where=[pd.Term('node_id', '==', 1)])                           

结果中只返回节点3:

                   time     GW_time  node_id    X      Y       Z status seq rssi lqi
299982  2013-10-22 17:30:50 59222464    3   19912   20838   22003   0   41  -64 48
299986  2013-10-22 17:30:50 59222720    3   19912   20838   22003   0   42  -64 48
299990  2013-10-22 17:30:50 59222976    3   19913   20840   22007   0   43  -64 50
299994  2013-10-22 17:30:50 59223232    3   19913   20840   22007   0   44  -64 50
299998  2013-10-22 17:30:50 59223488    3   19915   20840   22003   0   45  -64 48
300002  2013-10-22 17:30:50 59223744    3   19915   20840   22003   0   46  -64 50
300006  2013-10-22 17:30:50 59224000    3   19913   20844   22002   0   47  -64 48
300010  2013-10-22 17:30:50 59224256    3   19913   20844   22002   0   48  -64 50
300014  2013-10-22 17:30:50 59224512    3   19914   20844   22010   0   49  -64 49
300018  2013-10-22 17:30:50 59224768    3   19914   20844   22010   0   50  -64 50                         

然后我尝试使用索引而不是像这样开始/停止:

chunk = hdf.select('raw_sample_all', 
                   where=[pd.Term('index', '>=', 300002-20),
                          pd.Term('index', '<=', 300002+20),
                          pd.Term('node_id', '==', 1)])

这一次它返回了正确的结果:

                time        GW_time node_id  X       Y      Z   status seq rssi lqi
299984  2013-10-22 17:30:50 59222593    1   17613   22543   21203   0   42  -80 48
299988  2013-10-22 17:30:50 59222849    1   17613   22543   21203   0   43  -81 48
299992  2013-10-22 17:30:50 59223105    1   17610   22547   21194   0   44  -81 48
299996  2013-10-22 17:30:50 59223361    1   17610   22547   21194   0   45  -81 47
300000  2013-10-22 17:30:50 59223617    1   17609   22545   21190   0   46  -81 45
300004  2013-10-22 17:30:50 59223873    1   17609   22545   21190   0   47  -81 49
300008  2013-10-22 17:30:50 59224129    1   17606   22547   21199   0   48  -81 48
300012  2013-10-22 17:30:50 59224385    1   17606   22547   21199   0   49  -81 48
300016  2013-10-22 17:30:50 59224641    1   17607   22548   21191   0   50  -81 49
300020  2013-10-22 17:30:50 59224897    1   17607   22548   21191   0   51  -80 48  

我想我可能会通过索引选择来解决这个问题,但我不完全确定,因为带有 start/stop 的方法在大多数情况下也能得到正确的结果,所以即使带有 index 的方法在哪里得到了正确的结果启动/停止失败,它可能会在其他地方失败。

我真的很希望启动/停止方法能够工作,因为它要快得多,而且我有一个庞大的数据集,慢速方法真的很耗时。

顺便说一句,如果您想知道,我不能像这样使用“chunksize”:

df = hdf.select('raw_sample_all',chunksize=300000, where="node_id==1")
for chunk in df:
    print chunk.head(2)

每次我尝试 chunksize 时,我都会遇到像 this 这样的 MemoryError。 面对很多问题,Pandas 对于我这样的新手来说真的很难。 非常感谢任何帮助。

【问题讨论】:

【参考方案1】:

这是PyTables 中最近修复的错误,请参阅相关问题here。在使用wherestart/stop 时,在一些较大的存储中,索引器计算不正确。

您需要更新到PyTables 3.2,然后重新编写存储本身。您可以像第一次那样重新创建它,也可以使用ptrepack

【讨论】:

我使用 anaconda,我无法使用 conda update pytables 升级,它显示“已安装”。然后我试了pip install --upgrade tables,它说LINK : fatal error LNK1181: cannot open input file 'hdf5dll.lib' ... ERROR:: Could not find a local HDF5 installation. 我搜索了我的硬盘,找不到hdf5dll.lib文件。

以上是关于Python Pandas hdfstore 的 select(where='') 返回不合格的结果的主要内容,如果未能解决你的问题,请参考以下文章

Pandas HDFStore:省略重复项

Pandas HDFStore 从内存中卸载数据帧

使用 Pandas HDFStore 以只读模式打开文件

获取 HDF5 内容列表(Pandas HDFStore)

使用 Pandas 从大型 HDFStore 表中提高查询性能

pandas.HDFStore:如何修改现有商店的“data_columns”?我想为不在数据列中的列添加索引