从pandas groupby object

时间:2015-07-21 09:37:43

标签: python pandas

我正在尝试使用pandas的groupby功能,特别是

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

由于gb有50个组,结果很混乱,我想只探讨前5组的结果。

我找到了如何选择groupsget_groupHow to access pandas groupby dataframe by key)的单个群组,而不是如何直接选择多个群组。 我能做的最好的是:

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

有更直接的方法吗?

5 个答案:

答案 0 :(得分:7)

首先过滤你的df然后执行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

答案 1 :(得分:7)

您可以执行类似

的操作
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

答案 2 :(得分:2)

我不知道如何将.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()进行循环,这是一个非常好的。有点漂亮,但还是很难看。

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

答案 3 :(得分:1)

gbidx=list(gb.indices.keys())[:4]
dfidx=np.sort(np.concatenate([gb.indices[x] for x in gbidx]))
df.loc[dfidx].groupby('model').hist()

gb.indices比gb.groups或list(gb)快

我相信concat Index比concat DataFrames更快

我尝试了约416M行,13列(包括str)和720MB大小,并且按一个以上的列进行分组的大型csv文件

然后将列名更改为问题中的列名

答案 4 :(得分:0)

def get_groups(group_object):
    for i in group_object.groups.keys():
        print(f"____{i}____")
        display(group_object.get_group(i))


#get all groups by calling this method 

get_groups( any_group_which_you_made )