python--pandas分组聚合

分组聚合是数据处理中常见的场景,在pandas中用groupby方法实现分组操作,用agg方法实现聚合操作。

环境

  • python3.9
  • win10 64bit
  • pandas==1.2.1

groupby方法是pandas中的分组方法,对数据框采用groupby方法后,返回的是DataFrameGroupBy对象,一般分组操作后会进行聚合操作。

分组

import pandas as pd
import numpy as np
pd.set_option('display.notebook_repr_html',False)
# 数据准备
df = pd.DataFrame({'A': [1, 1, 2, 2],'B': [1, 2, 3, 4],'C':[6,8,1,9]})
df
   A  B  C
0  1  1  6
1  1  2  8
2  2  3  1
3  2  4  9

对数据框按A列进行分组,产生分组数据框。分组数据框是可迭代对象,可以进行循环遍历,可以看出在循环中,每个元素的类型是元组,
元组的第一个元素是分组值,第二个元素是对应的分组数据框。

# 分组
g_df=df.groupby('A')
# 分组数据框类
type(g_df)
pandas.core.groupby.generic.DataFrameGroupBy
# 循环分组数据
for i in g_df:
    print(i,type(i),end='\n\n')
(1,    A  B  C
0  1  1  6
1  1  2  8) <class 'tuple'>

(2,    A  B  C
2  2  3  1
3  2  4  9) <class 'tuple'>

可以对分组后的数据框直接使用聚合方法agg,对分组数据框的每一列计算统计函数值。

# 分组求和
df.groupby('A').agg('sum')
   B   C
A       
1  3  14
2  7  10

序列分组

可以根据数据框外的序列数据对数据框进行分组,需要注意序列长度需要与数据框行数相同

# 定义分组列表
label=['a','a','b','b']
# 分组求和
df.groupby(label).agg('sum')
   A  B   C
a  2  3  14
b  4  7  10

多列分组

可以根据数据框的多列对数据框进行分组。

# 数据准备
df = pd.DataFrame({'A': [1, 1, 2, 2],'B': [3, 4, 3, 3],'C':[6,8,1,9]})
df
   A  B  C
0  1  3  6
1  1  4  8
2  2  3  1
3  2  3  9

根据A,B列进行分组,然后求和。

# 根据多列分组求和
df.groupby(['A','B']).agg('sum')
      C
A B    
1 3   6
  4   8
2 3  10

索引分组

可以根据索引对数据框进行分组,需要设置level参数。

# 数据准备
df = pd.DataFrame({'A': [1, 1, 2, 2],'B': [3, 4, 3, 3],'C':[6,8,1,9]},index=['a','a','b','b'])
df
   A  B  C
a  1  3  6
a  1  4  8
b  2  3  1
b  2  3  9

数据框只有一层索引,设置参数level=0

# 根据索引分组求和
df.groupby(level=0).agg('sum')
   A  B   C
a  2  7  14
b  4  6  10

当数据框索引有多层时,也可以根据需求设置level参数,完成分组聚合。

# 数据准备
mi=pd.MultiIndex.from_arrays([[1,1,2,2],[3,4,3,3]],names=['id1','id2'])
df=pd.DataFrame(dict(value=[4,7,2,9]),index=mi)
df
         value
id1 id2       
1   3        4
    4        7
2   3        2
    3        9

设置level参数,如需要根据第一层索引,即id1进行分组,可以设置level=0level='id1'完成分组聚合。

# 根据第一层索引分组求和
df.groupby(level=0).agg('sum')
     value
id1       
1       11
2       11
# 根据第一层索引分组求和
df.groupby(level='id1').agg('sum')
     value
id1       
1       11
2       11

聚合

分组后一般会进行聚合操作,用agg方法进行聚合。

# 数据准备
df = pd.DataFrame({'A': [1, 1, 2, 2],'B': [3, 4, 3, 3],'C':[6,8,1,9],'D':[2,5,4,8]})
df
   A  B  C  D
0  1  3  6  2
1  1  4  8  5
2  2  3  1  4
3  2  3  9  8

单函数对多列

对分组后数据框使用单个函数进行聚合,单个聚合函数会对每列进行计算,然后合并返回。聚合函数以字符串的形式传入。

# 对所有列分组求和
df.groupby('A').agg('sum')
   B   C   D
A           
1  7  14   7
2  6  10  12

可以对分组后的数据指定列进行分组聚合。需要注意子列需要用[]包裹

# 对指定列分组求和
df.groupby('A')[['B','C']].agg('sum')
   B   C
A       
1  7  14
2  6  10

聚合函数也可以传入自定义的匿名函数。

# 匿名函数分组求和
df.groupby('A').agg(lambda x:sum(x))
   B   C   D
A           
1  7  14   7
2  6  10  12

多函数对多列

聚合函数可以是多个函数。聚合时,多个聚合函数会对每列进行计算,然后合并返回。聚合函数以列表的形式传入。

# 全部列多函数聚合
df.groupby('A').agg(['sum','mean'])
    B        C        D     
  sum mean sum mean sum mean
A                           
1   7  3.5  14    7   7  3.5
2   6  3.0  10    5  12  6.0

聚合返回后的数据列名有两层索引,第一层是聚合的列名,第二层是使用的聚合函数名。如果需要对返回的聚合函数名重命名,
需要在传参时,传入元组,第一个元素为聚合函数名,第二个元素为聚合函数。

# 聚合函数重命名
df.groupby('A').agg([('SUM','sum'),('MEAN','mean')])

    B        C        D     
  SUM MEAN SUM MEAN SUM MEAN
A                           
1   7  3.5  14    7   7  3.5
2   6  3.0  10    5  12  6.0

同样,也可以传入匿名函数。

# 匿名函数并重命名
df.groupby('A').agg([('SUM','sum'),('MAX',lambda x:max(x))])
    B       C       D    
  SUM MAX SUM MAX SUM MAX
A                        
1   7   4  14   8   7   5
2   6   3  10   9  12   8

如果需要对不同的列进行不同的聚合计算,则需要传入字典的形式。

# 不同列不同聚合函数
df.groupby('A').agg({'B':['sum','mean'],'C':'mean'})
    B         C
  sum mean mean
A              
1   7  3.5    7
2   6  3.0    5

可以重命名聚合后的列名,注意只能对一列传入一个聚合函数时有效

# 聚合后重命名列名
df.groupby('A').agg(B_sum=('B','sum'),C_mean=('C','mean'))
   B_sum  C_mean
A               
1      7       7
2      6       5
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,835评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,598评论 1 295
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,569评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,159评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,533评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,710评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,923评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,674评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,421评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,622评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,115评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,428评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,114评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,097评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,875评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,753评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,649评论 2 271

推荐阅读更多精彩内容

  • 在日常数据分析时,经常会遇到需要按列分组 (groupby) 的任务,如计算某公司各部门的人数,计算各部门男女平均...
    心宇gxy阅读 480评论 0 1
  • Pandas分组聚合 - 基础 数据分析阶段: 数据规整(清洗)阶段后,下一阶段就是 分组聚合 对数据集分组并对各...
    羋学僧阅读 461评论 0 3
  • 一、数据分组 1.groupby简介 groupby的运算核心为split-apply-combine,首先,数据...
    文嘉达_0da8阅读 418评论 0 0
  • 数据的分组运算和聚合 在将数据集加载、融合、准备好之后,通常就是计算分组统计或⽣成透视表, pandas提供了⼀个...
    222AblackA阅读 225评论 0 1
  • 最后一次更新日期: 2019/4/20 pandas是基于numpy的数据分析库,提供一些更易用的数据模型和大量高...
    jiedawang阅读 1,384评论 0 5