2013-07-27 34 views
4

我想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數據庫文件的必備條件? –

回答

7

這是一個完整的例子。

創建具有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輸出? –

9

我已經測試了幾個的傑夫在我們的健談的討論提到了上述選項。

請看看這款筆記本,希望這將有助於你做出相關決定爲您的數據存儲: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

非常有趣的東西,謝謝。要公平地使用壓縮算法,請記住您使用的是隨機數據(難以壓縮)。使用「真實」數據時,使用壓縮時可能會顯着減小文件大小。 –