Pandas groupby在保留多个聚合的组内进行排序

时间:2018-01-23 02:37:02

标签: python pandas sorting pandas-groupby

我想在groupby返回的组中应用排序和限制,如this question中所示。但是,我有多个聚合,我希望所有聚合都保留在结果中。

这是一个简单的例子:

products = ["A", "B", "C", "D"]
stores = ["foo", "bar", "baz"]
n = 30

product_list = [products[i] for i in np.random.randint(0, len(products), n)]
store_list = [stores[i] for i in np.random.randint(0, len(stores), n)]
rating_list = np.random.random(n) * 5
sales_list = np.random.random(n) * 10000

df = pd.DataFrame(
    {'store': store_list, 
     'product': product_list, 
     'sales': sales_list, 
     'rating': rating_list})

df = df[['store', 'product', 'sales', 'rating']]

df[:5]

ungrouped dataframe

我希望按storeproduct以及sumcount sales分组,同时取mean的{​​{1}} rating

这很简单:

dfg = df.groupby(['store', 'product']).agg({'sales': ['sum', 'count'], 
                                            'rating': 'mean'})

grouped

现在,我想只保留每组中排名前两位的行。我可以如下得到这个(使用1中有点不直观[对我来说]咒语的多级扩展:

g = dfg[('rating', 'mean')].groupby(
      level=0, group_keys=False).apply(
        lambda x: x.sort_values(ascending=False).head(2))
g

这将返回以下Series

store  product
bar    B          3.601135
       A          1.867449
baz    B          2.984196
       D          2.780500
foo    B          3.767912
       D          3.129346
Name: (rating, mean), dtype: float64

但我已经丢失了('sales', 'sum')('sales', 'count')列。

我怀疑我需要提取g.index并以某种方式使用它,但无法将其排序(双关语)。

编辑:下面的答案设法给了我正在寻找的小组,但我真正喜欢的是一种稳定的排序,我不仅得到每组中的前N个平均评分,但是这些团体本身的排序是为了让第一组获得最高等级,等等。在某种程度上,这只是锦上添花,因为我现在拥有我想要的价值,并希望报告更漂亮。

2 个答案:

答案 0 :(得分:2)

我已经对它进行了分类。我没有将分组表编入索引并执行上述后续groupbysort_values,而是将sort_values应用于未编入索引的DataFrame,指定要排序的列明确地说:

g = dfg.groupby(level=0, group_keys=False).apply(
      lambda x: x.sort_values(('rating', 'mean'), ascending=False).head(2))

给我想要的结果:

enter image description here

答案 1 :(得分:2)

这是您使用sort_values + groupby + head -

的方式
dfg.sort_values(('rating', 'mean'), ascending=False)\
   .groupby(level=0)\
   .head(2)\
   .sort_index()

                 rating         sales      
                   mean           sum count
store product                              
bar   B        4.388521    636.813757     1
      C        3.931341   1843.772878     1
baz   A        2.501077  23110.162196     4
      B        3.339784  10610.257660     2
foo   B        2.785306  10315.968161     2
      D        2.160556  31084.181719     5

最终的sort_index调用会排除索引无序问题(双关语)。