ptrepack sortby需要'全'索引

问题描述:

我想ptrepack一个HDF文件,它是用大熊猫HDFStore pytables界面创建的。 数据帧的主要索引是时间,但我做了更多的列data_columns,以便我可以通过这些data_columns过滤磁盘上的数据。ptrepack sortby需要'全'索引

现在我想排序的列之一的HDF文件(因为选择是对我的口味,84 GB的文件太慢),采用ptrepack与sortby选项,如下所示:

()[[email protected] .../nominal]$ ptrepack --chunkshape=auto --propindexes --complevel=9 --complib=blosc --sortby=clat C9.h5 C9_sorted.h5 

我得到的错误信息:

()[[email protected] .../nominal]$ Problems doing the copy from 'C9.h5:/' to 'C9_sorted.h5:/' The error was --> : Field clat must have associated a 'full' index in table /df/table (Table(390557601,)) '' . The destination file looks like: C9_sorted.h5 (File) '' Last modif.: 'Fri Jul 26 18:17:56 2013' Object Tree:/ (RootGroup) '' /df (Group) '' /df/table (Table(0,), shuffle, blosc(9)) ''

Traceback (most recent call last): File "/usr/local/epd/bin/ptrepack", line 10, in sys.exit(main()) File "/usr/local/epd/lib/python2.7/site-packages/tables/scripts/ptrepack.py", line 480, in main upgradeflavors=upgradeflavors) File "/usr/local/epd/lib/python2.7/site-packages/tables/scripts/ptrepack.py", line 225, in copyChildren raise RuntimeError("Please check that the node names are not " RuntimeError: Please check that the node names are not duplicated in destination, and if so, add the --overwrite-nodes flag if desired. In particular, pay attention that rootUEP is not fooling you.

这是否意味着,我不能排序的索引列HDF文件,因为它们不是“全”索引?

+0

我认为这是正确的。默认的指示是“轻”,6级IIRC。请参阅http://pandas.pydata.org/pandas-docs/dev/io.html#indexing。改为9级,'全'等同于创建一个CSI。你可以通过print store.get_storer('df') – Jeff

+0

看到关于表格的更多信息,也尝试去掉--propindices,我认为它可能与排序不兼容 – Jeff

+0

但是当我省略propindices时,我无法在磁盘上进行过滤数据,这是84 GB数据库文件的必备条件? –

这是一个完整的例子。

创建具有data_column帧。将索引重置为完整索引。使用ptrepack至 sortby它。

In [16]: df = DataFrame(randn(10,2),columns=list('AB')).to_hdf('test.h5','df',data_columns=['B'],mode='w',table=True) 

In [17]: store = pd.HDFStore('test.h5') 

In [18]: store 
Out[18]: 
<class 'pandas.io.pytables.HDFStore'> 
File path: test.h5 
/df   frame_table (typ->appendable,nrows->10,ncols->2,indexers->[index],dc->[B]) 

In [19]: store.get_storer('df').group.table 
Out[19]: 
/df/table (Table(10,)) '' 
    description := { 
    "index": Int64Col(shape=(), dflt=0, pos=0), 
    "values_block_0": Float64Col(shape=(1,), dflt=0.0, pos=1), 
    "B": Float64Col(shape=(), dflt=0.0, pos=2)} 
    byteorder := 'little' 
    chunkshape := (2730,) 
    autoIndex := True 
    colindexes := { 
    "index": Index(6, medium, shuffle, zlib(1)).is_CSI=False, 
    "B": Index(6, medium, shuffle, zlib(1)).is_CSI=False} 

In [20]: store.create_table_index('df',columns=['B'],optlevel=9,kind='full') 

In [21]: store.get_storer('df').group.table 
Out[21]: 
/df/table (Table(10,)) '' 
    description := { 
    "index": Int64Col(shape=(), dflt=0, pos=0), 
    "values_block_0": Float64Col(shape=(1,), dflt=0.0, pos=1), 
    "B": Float64Col(shape=(), dflt=0.0, pos=2)} 
    byteorder := 'little' 
    chunkshape := (2730,) 
    autoIndex := True 
    colindexes := { 
    "index": Index(6, medium, shuffle, zlib(1)).is_CSI=False, 
    "B": Index(9, full, shuffle, zlib(1)).is_CSI=True} 

In [22]: store.close() 

In [25]: !ptdump -avd test.h5 
/(RootGroup) '' 
    /._v_attrs (AttributeSet), 4 attributes: 
    [CLASS := 'GROUP', 
    PYTABLES_FORMAT_VERSION := '2.0', 
    TITLE := '', 
    VERSION := '1.0'] 
/df (Group) '' 
    /df._v_attrs (AttributeSet), 14 attributes: 
    [CLASS := 'GROUP', 
    TITLE := '', 
    VERSION := '1.0', 
    data_columns := ['B'], 
    encoding := None, 
    index_cols := [(0, 'index')], 
    info := {'index': {}}, 
    levels := 1, 
    nan_rep := b'nan', 
    non_index_axes := [(1, ['A', 'B'])], 
    pandas_type := b'frame_table', 
    pandas_version := b'0.10.1', 
    table_type := b'appendable_frame', 
    values_cols := ['values_block_0', 'B']] 
/df/table (Table(10,)) '' 
    description := { 
    "index": Int64Col(shape=(), dflt=0, pos=0), 
    "values_block_0": Float64Col(shape=(1,), dflt=0.0, pos=1), 
    "B": Float64Col(shape=(), dflt=0.0, pos=2)} 
    byteorder := 'little' 
    chunkshape := (2730,) 
    autoindex := True 
    colindexes := { 
    "index": Index(6, medium, shuffle, zlib(1)).is_csi=False, 
    "B": Index(9, full, shuffle, zlib(1)).is_csi=True} 
    /df/table._v_attrs (AttributeSet), 15 attributes: 
    [B_dtype := b'float64', 
    B_kind := ['B'], 
    CLASS := 'TABLE', 
    FIELD_0_FILL := 0, 
    FIELD_0_NAME := 'index', 
    FIELD_1_FILL := 0.0, 
    FIELD_1_NAME := 'values_block_0', 
    FIELD_2_FILL := 0.0, 
    FIELD_2_NAME := 'B', 
    NROWS := 10, 
    TITLE := '', 
    VERSION := '2.6', 
    index_kind := b'integer', 
    values_block_0_dtype := b'float64', 
    values_block_0_kind := ['A']] 
    Data dump: 
[0] (0, [1.10989047288066], 0.396613633081911) 
[1] (1, [0.0981650001268093], -0.9209780702446433) 
[2] (2, [-0.2429293157073629], -1.779366453624283) 
[3] (3, [0.7305529521507728], 1.243565083939927) 
[4] (4, [-0.1480724789512519], 0.5260130757651649) 
[5] (5, [1.2560020435792643], 0.5455842491255144) 
[6] (6, [1.20129355706986], 0.47930635538027244) 
[7] (7, [0.9973598999689721], 0.8602929579025727) 
[8] (8, [-0.40070941088441786], 0.7622228032635253) 
[9] (9, [0.35865804118145655], 0.29939126149826045) 

这是另一种方式来创建一个完全排序索引(而不是写这种方式)

In [23]: !ptrepack --sortby=B test.h5 test_sorted.h5 

In [26]: !ptdump -avd test_sorted.h5 
/(RootGroup) '' 
    /._v_attrs (AttributeSet), 4 attributes: 
    [CLASS := 'GROUP', 
    PYTABLES_FORMAT_VERSION := '2.1', 
    TITLE := '', 
    VERSION := '1.0'] 
/df (Group) '' 
    /df._v_attrs (AttributeSet), 14 attributes: 
    [CLASS := 'GROUP', 
    TITLE := '', 
    VERSION := '1.0', 
    data_columns := ['B'], 
    encoding := None, 
    index_cols := [(0, 'index')], 
    info := {'index': {}}, 
    levels := 1, 
    nan_rep := b'nan', 
    non_index_axes := [(1, ['A', 'B'])], 
    pandas_type := b'frame_table', 
    pandas_version := b'0.10.1', 
    table_type := b'appendable_frame', 
    values_cols := ['values_block_0', 'B']] 
/df/table (Table(10,)) '' 
    description := { 
    "index": Int64Col(shape=(), dflt=0, pos=0), 
    "values_block_0": Float64Col(shape=(1,), dflt=0.0, pos=1), 
    "B": Float64Col(shape=(), dflt=0.0, pos=2)} 
    byteorder := 'little' 
    chunkshape := (2730,) 
    /df/table._v_attrs (AttributeSet), 15 attributes: 
    [B_dtype := b'float64', 
    B_kind := ['B'], 
    CLASS := 'TABLE', 
    FIELD_0_FILL := 0, 
    FIELD_0_NAME := 'index', 
    FIELD_1_FILL := 0.0, 
    FIELD_1_NAME := 'values_block_0', 
    FIELD_2_FILL := 0.0, 
    FIELD_2_NAME := 'B', 
    NROWS := 10, 
    TITLE := '', 
    VERSION := '2.6', 
    index_kind := b'integer', 
    values_block_0_dtype := b'float64', 
    values_block_0_kind := ['A']] 
    Data dump: 
[0] (2, [-0.2429293157073629], -1.779366453624283) 
[1] (1, [0.0981650001268093], -0.9209780702446433) 
[2] (9, [0.35865804118145655], 0.29939126149826045) 
[3] (0, [1.10989047288066], 0.396613633081911) 
[4] (6, [1.20129355706986], 0.47930635538027244) 
[5] (4, [-0.1480724789512519], 0.5260130757651649) 
[6] (5, [1.2560020435792643], 0.5455842491255144) 
[7] (8, [-0.40070941088441786], 0.7622228032635253) 
[8] (7, [0.9973598999689721], 0.8602929579025727) 
[9] (3, [0.7305529521507728], 1.243565083939927) 
+0

谢谢!当我将另一个数据帧附加到在该列上具有完整索引的商店吗?它会自动继续吗?还是需要在最终文件上执行store.create_table_index?它是否发生在磁盘上,因此不会在我的商店增长时产生内存问题到80 Gigs? –

+0

我想当你追加它将索引到新的方案。你真正需要sortby的唯一原因是强制它重新索引(你实际上也可以通过pytables函数调用来做到这一点,这是什么sortby在做什么) – Jeff

+0

pandas_version:= b'0.10.1''在ptdump输出? –

我已经测试了几个的杰夫在我们的健谈的讨论提到了上述选项。

请看看这款笔记本,希望这将有助于你做出相关决定为您的数据存储:http://nbviewer.ipython.org/810bd0720bb1732067ff 对于笔记本的要点是在这里:https://gist.github.com/michaelaye/810bd0720bb1732067ff

我的主要结论:

  • 使用index = False有几个令人印象深刻的效果:1.它减小了生成的HDF文件的文件大小。它更快地创建HDFFile。 3.即使如此,ptdump和storer().group.table打印输出也不显示任何索引,商店显示仍然显示索引器和数据列(这可能无视我自己的pytables机器)。
  • 创建经由store.create_table_index索引()经由数据列中的一个不执行任何尚未数据选择的速度。
  • 此索引HAS是一个'完整'索引,以便后面的带有--sortby的ptrepack不保释。但它确实是而不是必须是索引级别9.默认级别6很好,似乎不会显着影响数据选择速度。也许它会尽管有很多专栏?
  • 使用-propindexes几乎使ptrepacking时间增加一倍,数据选择速度略有提高。
  • 使用压缩和--propindexs仅比使用--propindex稍慢,而数据大小(至少在本例中)不会显着下降。
  • 通过使用压缩,数据选择速度似乎没有太大差异。
  • 这个1Mio的例子的加速。 2列随机数据的行通过使用--sortby无--propindexes约为选择列的排序后的因子5。

完成,命令的超短摘要:

df = pd.DataFrame(randn(1e6,2),columns=list('AB')).to_hdf('test.h5','df', 
        data_columns=list('AB'),mode='w',table=True,index=False) 
store = pd.HDFStore('test.h5') 
store.create_table_index('df',columns=['B'], kind='full') 
store.close() 

而且在外壳:

ptrepack --chunkshape=auto --sortby=B test.h5 test_sorted.h5 
+0

@K“商店展示仍然显示索引器和数据列(这可能不知道我的方面的pytables机器)” –

+1

... - 如果我理解你正确地说,使用术语“索引”会产生混淆 - 而对于大熊猫,这是行和列的索引器,在pyTables中,这是查询的索引(所以没有索引是在pyTables一侧完成的,而列是您使用'data_columns = ...'调用的索引器)。我个人不确定的是自动生成的“列”标题为“索引”的需要。据我了解这枚举的行,但我相信这已经内置在pyTables –

+0

非常有趣的东西,谢谢。要公平地使用压缩算法,请记住您使用的是随机数据(难以压缩)。使用“真实”数据时,使用压缩时可能会显着减小文件大小。 –