2013-04-03 7 views
20

私は約60万の列を持つHDFStoreに約700万行あります。データは私がメモリに収めること以上のものです。私は、列 "A"の値に基づいてグループにデータを集約しようとしています。パンダsplitting/aggregating/combiningのドキュメントでは、すべてのデータがすでにDataFrameにあると仮定していますが、店舗全体をメモリ内のDataFrameに読み取ることはできません。 HDFStoreでデータをグループ化する正しい方法は何ですか?パンダの「Group By」HDFStoreの大規模データのクエリ?

+1

のために働くあなたがhttp://stackoverflow.com/questions/14262433/large-dataを見ている場合は私に知らせて-work-flows-using-pandas/14287518#14287518? Jeffの答えは、このタイプのワークフローに適した初級者です。 –

+1

これは、現在、パンダの将来の拡張として議論されています。私は最終的にSASを捨てることができるようになることを祈っています。https://github.com/pydata/pandas/issues/3202 – Zelazny7

+0

ドキュメントを理解すると、HDFStoresはDataFramesで利用できるすべての操作をサポートしていません。一度に1つのグループを手動で選択するには、[ここ](http://pandas.pydata.org/pandas-docs/dev/io.html#query-via-data-columns)で説明されているテーブルクエリ機能を試してみてください。 – BrenBarn

答えて

16

Heres完全な例。

import numpy as np 
import pandas as pd 
import os 

fname = 'groupby.h5' 

# create a frame 
df = pd.DataFrame({'A': ['foo', 'foo', 'foo', 'foo', 
         'bar', 'bar', 'bar', 'bar', 
         'foo', 'foo', 'foo'], 
        'B': ['one', 'one', 'one', 'two', 
         'one', 'one', 'one', 'two', 
         'two', 'two', 'one'], 
        'C': ['dull', 'dull', 'shiny', 'dull', 
         'dull', 'shiny', 'shiny', 'dull', 
         'shiny', 'shiny', 'shiny'], 
        'D': np.random.randn(11), 
        'E': np.random.randn(11), 
        'F': np.random.randn(11)}) 


# create the store and append, using data_columns where I possibily 
# could aggregate 
with pd.get_store(fname) as store: 
    store.append('df',df,data_columns=['A','B','C']) 
    print "store:\n%s" % store 

    print "\ndf:\n%s" % store['df'] 

    # get the groups 
    groups = store.select_column('df','A').unique() 
    print "\ngroups:%s" % groups 

    # iterate over the groups and apply my operations 
    l = [] 
    for g in groups: 

     grp = store.select('df',where = [ 'A=%s' % g ]) 

     # this is a regular frame, aggregate however you would like 
     l.append(grp[['D','E','F']].sum()) 


    print "\nresult:\n%s" % pd.concat(l, keys = groups) 

os.remove(fname) 

出力

store: 
<class 'pandas.io.pytables.HDFStore'> 
File path: groupby.h5 
/df   frame_table (typ->appendable,nrows->11,ncols->6,indexers->[index],dc->[A,B,C]) 

df: 
     A B  C   D   E   F 
0 foo one dull -0.815212 -1.195488 -1.346980 
1 foo one dull -1.111686 -1.814385 -0.974327 
2 foo one shiny -1.069152 -1.926265 0.360318 
3 foo two dull -0.472180 0.698369 -1.007010 
4 bar one dull 1.329867 0.709621 1.877898 
5 bar one shiny -0.962906 0.489594 -0.663068 
6 bar one shiny -0.657922 -0.377705 0.065790 
7 bar two dull -0.172245 1.694245 1.374189 
8 foo two shiny -0.780877 -2.334895 -2.747404 
9 foo two shiny -0.257413 0.577804 -0.159316 
10 foo one shiny 0.737597 1.979373 -0.236070 

groups:Index([bar, foo], dtype=object) 

result: 
bar D -0.463206 
    E 2.515754 
    F 2.654810 
foo D -3.768923 
    E -4.015488 
    F -6.110789 
dtype: float64 

いくつかの注意事項:あなたのグループの密度が比較的低い場合

1)この方法論は意味があります。数百または数千のグループのオーダー。それ以上のものが得られれば、より効率的ですがもっと複​​雑なメソッドがあり、適用する関数(この場合はsum)がより制限的になります。

本質的には、ストア全体を繰り返し、繰り返しながらグループ化しますが、グループを半縮ませたままにしておきます(平均していると想像してください。したがって、実行中の合計に実行回数を加え、最後に)。だから、いくつかの操作はややこしいかもしれませんが、潜在的に多くのグループを扱うことができます(そして、本当に速いです)。

2)の効率は、座標(例えば、グループの位置を保存することによって向上させることができ、これはもう少し複雑である)

3)マルチグルーピングこの方式では不可能である(それが可能ですしかし、2)以上のようなアプローチが必要です

4)グループ化する列はdata_columnでなければなりません!

5)選択したbtwで他のフィルタを組み合わせることができます(これは、マルチグループ化btwのやっかいな方法です。グループと反復子の2つのユニークなリストを生成します。あなたは、グループの多くを持っていますが、働くことができる場合)

HTH

が、これはあなた

+1

方法2はここに記述されています:https://github.com/pydata/pandas/issues/3202 – Jeff

+0

ありがとうございました。私は、この例(とSOへのリンク!)をgitチケットに追加することができたら、ボーナスポイントを与えます。 – technomalogical

+0

hahha ....喜んで – Jeff