Python: 对于多维groupby()透视数据,筛选保留分组的前N个最大/最小数据?

本文介绍如何使用Python Pandas库对DataFrame数据进行分组(groupby)并按特定字段进行排序,提供了两种方法:一是使用nlargest()函数实现快速降序排序及截取;二是利用sort_values()结合head()函数实现更灵活的数据排序与截取。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

stackoverflow原问答链接

问题: 需要把dataframe,先进行gourpby()处理、再对结果进行排序:

 """现有数据如下:"""
# print(df)
count   job source
0   2   sales   A
1   4   sales   B
2   6   sales   C
3   3   sales   D
4   7   sales   E
5   5   market  A
6   3   market  B
7   2   market  C
8   4   market  D
9   1   market  E

df_gb = df.groupby(['job', 'source']).agg({'count':sum}) 
#print(df_groupby)
               count           # note: 此处有“count”
job    source       
market A           5
       B           3
       C           2
       D           4
       E           1
sales  A           2
       B           4
       C           6
       D           3
       E           7

我想要:的结果是groupby()里边count降序排列、取每个group的前3数据:

job     source  #(本列count)
market  A       5
        D       4
        B       3
sales   E       7
        C       6
        B       4

方法一:直接使用nlargest()

df_gb = df.groupby(['job', 'source']).agg({'count':sum})

g = df_gb ['count'].groupby(level=0, group_keys=False)  # 更多信息见下边备注
res = g.nlargest(3)

print(res)

 # res输出结果如下:
 job     source  #(本列count)
market  A         5
        D         4
        B         3
sales   E         7
        C         6
        B         4
dtype: int64
  • g = df_gb ['count'].groupby(level=0, group_keys=False)
  • 为什么使用df_gb['count'].groupby(level=0),而不是df_gb.groupby(by=['count'], level=0)
  • 为什么.groupby()里边需要level=0?
    因为"by"和"level"在groupby函数至少得有一个。 这里指的是job列。
  • 不设置group_keys=False会怎样?
    会有2个"job"列。 它保证了原index值在结果的group里被保留,并且没有额外level的group标签。
  • .groupby()里边参数bylevel只能取其中1个。
  • res = g.nlargest(3)等价于
    res = g.apply(lambda x: x.order(ascending=False).head(3)

其他:

.nlargest()似乎结果只保留单个value的结果,例如df_gb ['count'],即使df_gb里有其他类似count的统计值也不会被保留。典型场景如Pandas.pivot_table(columns=my_column),下边的方法二则会保留所有的

方法二:sort_values() 搭配 head()

haha = df.sort_values(['job', 'count'], ascending=False).groupby('job').head(3)
print(haha)
# haha输出结果如下:
     count   job    source # 这一次显示“列名称” & 也没有增减“列” & 也没有改变“列”的顺序
4      7   sales      E
2      6   sales      C
1      4   sales      B
5      5  market      A
8      4  market      D
6      3  market      B


备注:

  • nlargest()在下列情况不能使用,因为没有count字段:
df_groupby = df.groupby(['job', 'source'])['count'].sum()
print(df_groupby)

                   # 这里没有count,导致g = df_groupby['count']不存在。
job     source     
market  A         5
        B         3
        C         2
        D         4
        E         1
sales   A         2
        B         4
        C         6
        D         3
        E         7
  • groupby()pd.pivot_table()的结果会删除有NaN的行的结果,这和merge()concat()join()等函数不同,[引用链接]
df = pd.DataFrame({'col1':[np.nan, 'match', np.nan], 'col2':[1,2,1]})
print(df.groupby('col1').sum())

# 结果如下:
       col2
col1    
match   2 

# 而不是
       col2
col1    
match   2 
NaN     2
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值