Подтвердить что ты не робот

Pandas "Группировка по" Запрос больших данных в HDFStore?

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

4b9b3361

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

НТН

сообщите мне, если это сработает для вас