Pandas "Group By" запрос на большие данные в HDFStore?

у меня около 7 миллионов строк в HDFStore с более чем 60 колонок. Данные больше, чем я могу вместить в память. Я ищу, чтобы объединить данные в группы на основе значения столбца "а". Документация для панд разделения/объединения/объединения предполагает, что у меня есть все мои данные в DataFrame уже, Однако я не могу прочитать весь магазин в память DataFrame. Каков правильный подход для группировки данных в HDFStore?

1 ответов


вот полный пример.

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) Вы можете объединить любой другой фильтр, который вы хотите в select btw (который является скрытым способом сделать мульти-группировку btw, вы просто формируете 2 уникальных списка группы и итератора над их продуктом, не очень эффективным, если у вас есть много групп, но может работать)

HTH

позвольте мне знать, если это работает для вы