2015-07-21 3 views
6

Я экспериментировал с особенностями GroupBy панды, в частностиВыберите несколько групп из панда GroupBy объекта

gb = df.groupby('model') 
gb.hist() 

С гб имеет 50 групп результат довольно суматоха, я хотел бы изучить результат только для первые 5 групп.

Я нашел, как выбрать одну группу с groups или get_group (How to access pandas groupby dataframe by key), но не как выбрать несколько групп напрямую. Лучшее, что я мог сделать, это:

groups = dict(list(gb)) 
subgroup = pd.concat(groups.values()[:4]) 
subgroup.groupby('model').hist() 

Есть ли более прямой путь?

+0

Выбор первых n групп немного расплывчато, возможно, вы имеете в виду **, как вы можете присоединить первые n групп к единому файловому кадру ** .. что-то вдоль этих строк? А также, как бы вы хотели выбрать группы? Случайно или в зависимости от населения группы и т. Д.? – dermen

+0

На данный момент я просто выбираю их по их заказу, немного похоже на использование head() или tail() только для того, чтобы иметь представление о том, как выглядят данные.Я думаю, что мой метод уже присоединяется к первым группам в одном фреймворке данных, но было бы неплохо и более эффективное решение – lib

+1

, вы можете получить группы, просто позвонив в раздел «gp.groups»: http: //pandas.pydata.org /pandas-docs/stable/generated/pandas.core.groupby.GroupBy.groups.html#pandas.core.groupby.GroupBy.groups, вам может быть лучше просто отфильтровать ваш df, поэтому df_filt = df [df ['model '] .isin (df [' model ']. unique() [: 5])] 'then' gb = df_filt.groupby (' model ') '#rest кода такой же, как раньше – EdChum

ответ

4

Вы можете сделать что-то вроде

new_gb = pandas.concat([ gb.get_group(group) for i,group in enumerate(gb.groups) if i < 5 ]).groupby('model')  
new_gb.hist() 

Хотя, я бы подойти к нему по-другому , Вы можете использовать collections.Counter объект, чтобы получить группы быстро:

import collections 

df = pandas.DataFrame.from_dict({'model': pandas.np.random.randint(0, 3, 10), 'param1': pandas.np.random.random(10), 'param2':pandas.np.random.random(10)}) 
# model param1 param2 
#0  2 0.252379 0.985290 
#1  1 0.059338 0.225166 
#2  0 0.187259 0.808899 
#3  2 0.773946 0.696001 
#4  1 0.680231 0.271874 
#5  2 0.054969 0.328743 
#6  0 0.734828 0.273234 
#7  0 0.776684 0.661741 
#8  2 0.098836 0.013047 
#9  1 0.228801 0.827378 
model_groups = collections.Counter(df.model) 
print(model_groups) #Counter({2: 4, 0: 3, 1: 3}) 

Теперь вы можете перебрать Counter объект как словарь, и запрос группы, которые вы хотите:

new_df = pandas.concat([df.query('model==%d'%key) for key,val in model_groups.items() if val < 4 ]) # for example, but you can select the models however you like 
# model param1 param2 
#2  0 0.187259 0.808899 
#6  0 0.734828 0.273234 
#7  0 0.776684 0.661741 
#1  1 0.059338 0.225166 
#4  1 0.680231 0.271874 
#9  1 0.228801 0.827378 

Теперь вы можете использовать встроенный -в pandas.DataFrame.groupby функция

gb = new_df.groupby('model') 
gb.hist() 

с model_groups содержит все группы, вы можете просто выбрать из него, как вы хотите.

примечание

model Если столбец содержит строковые значения (имена или что-то) вместо целых чисел, все это будет работать так же - просто измените аргумент запроса от 'model==%d'%key к 'model=="%s"'%key.

0

Я не знаю, как использовать .get_group() method с несколькими группами.

Вы можете однако iterate through groups

Это еще немного некрасиво, чтобы сделать это, но вот одно из решений с итерацией:

limit = 5 
i = 0 
for key, group in gd: 
    print key, group 
    i += 1 
    if i >= limit: 
     break 

Вы также можете сделать петлю с .get_group(), который IMHO. немного красивее, но все же довольно уродливое.

for key in gd.groups.keys()[:2]: 
    print gd.get_group(key) 
+0

Чтобы использовать .get_group () с более чем одной группой, вам необходимо передать кортеж со значениями для key1 и значениями для key2 ... – user2265478

3

Было бы проще просто фильтровать ФР первый, а затем выполнить GroupBy:

In [155]: 

df = pd.DataFrame({'model':np.random.randint(1,10,100), 'value':np.random.randn(100)}) 
first_five = df['model'].sort(inplace=False).unique()[:5] 
gp = df[df['model'].isin(first_five)].groupby('model') 
gp.first() 
Out[155]: 
      value 
model   
1  -0.505677 
2  1.217027 
3  -0.641583 
4  0.778104 
5  -1.037858 
Смежные вопросы