模块四-数据转换与操作——26. groupby 基础

📅 2026/7/3 3:34:54 👁️ 阅读次数 📝 编程学习
模块四-数据转换与操作——26. groupby 基础

26. groupby 基础

1. 概述

groupby是 Pandas 中最强大的功能之一,它实现了"拆分-应用-合并"(Split-Apply-Combine)操作模式,用于对数据进行分组聚合分析。

importpandasaspdimportnumpyasnp# 创建示例数据np.random.seed(42)df=pd.DataFrame({'部门':['技术','销售','技术','市场','销售','技术','市场','销售'],'姓名':['张三','李四','王五','赵六','钱七','孙八','周九','吴十'],'工资':[8000,12000,10000,15000,11000,9500,10500,12500],'年龄':[25,30,28,32,35,27,29,31],'绩效':['A','B','A','A','C','B','A','B']})print("原始数据:")print(df)

2. groupby 基础操作

2.1 单列分组

# 按部门分组grouped=df.groupby('部门')print("分组对象:",grouped)print(f"分组数:{len(grouped)}")# 查看各组forname,groupingrouped:print(f"\n部门:{name}")print(group)

2.2 多列分组

# 按部门和绩效分组grouped_multi=df.groupby(['部门','绩效'])for(dept,perf),groupingrouped_multi:print(f"\n部门={dept}, 绩效={perf}")print(group[['姓名','工资']])

3. 分组聚合

3.1 基础聚合函数

# 单列聚合print("各部门平均工资:")print(df.groupby('部门')['工资'].mean())print("\n各部门工资总和:")print(df.groupby('部门')['工资'].sum())print("\n各部门人数:")print(df.groupby('部门')['姓名'].count())print("\n各部门工资统计:")print(df.groupby('部门')['工资'].agg(['mean','sum','min','max','std']))

3.2 多列聚合

# 对多列应用相同聚合print("各部门工资和年龄统计:")print(df.groupby('部门')[['工资','年龄']].mean())# 对多列应用不同聚合print("\n各部门统计(工资求和,年龄平均):")print(df.groupby('部门').agg({'工资':'sum','年龄':'mean'}))

3.3 多种聚合函数

# 使用 agg 同时应用多个函数result=df.groupby('部门')['工资'].agg(['mean','median','min','max','std','count'])print("多种聚合:")print(result)# 重命名聚合列result=df.groupby('部门').agg(平均工资=('工资','mean'),最高工资=('工资','max'),最低工资=('工资','min'),人数=('姓名','count'))print("\n重命名聚合列:")print(result)

4. 分组后选择列

# 选择单列分组dept_avg_salary=df.groupby('部门')['工资'].mean()print("各部门平均工资:")print(dept_avg_salary)# 选择多列dept_stats=df.groupby('部门')[['工资','年龄']].agg(['mean','max'])print("\n各部门工资和年龄统计:")print(dept_stats)

5. 分组遍历

# 遍历分组dept_summary=[]forname,groupindf.groupby('部门'):summary={'部门':name,'人数':len(group),'平均工资':group['工资'].mean(),'最高工资':group['工资'].max(),'最年轻':group['年龄'].min()}dept_summary.append(summary)result=pd.DataFrame(dept_summary)print("分组遍历结果:")print(result)

6. 分组后获取特定组

# 获取特定组tech_group=df.groupby('部门').get_group('技术')print("技术部门:")print(tech_group)# 获取所有组的索引groups=df.groupby('部门').groupsprint("\n各组索引:")print(groups)

7. 完整示例:销售数据分析

# 创建销售数据np.random.seed(42)sales=pd.DataFrame({'日期':pd.date_range('2024-01-01',periods=100,freq='D'),'产品':np.random.choice(['产品A','产品B','产品C'],100),'地区':np.random.choice(['华东','华南','华北','西南'],100),'销售额':np.random.randint(1000,10000,100),'销量':np.random.randint(10,200,100),'销售员':np.random.choice(['张三','李四','王五'],100)})print("="*60)print("销售数据分析")print("="*60)print("\n原始数据:")print(sales.head())# 1. 按产品分组统计print("\n1. 各产品销售额统计:")product_stats=sales.groupby('产品').agg({'销售额':['sum','mean','max'],'销量':'sum'}).round(2)print(product_stats)# 2. 按地区分组统计print("\n2. 各地区销售情况:")region_stats=sales.groupby('地区').agg({'销售额':'sum','销量':'sum','销售员':'nunique'}).rename(columns={'销售员':'销售员数'})print(region_stats)# 3. 按产品和地区分组print("\n3. 产品×地区销售矩阵:")pivot=sales.groupby(['产品','地区'])['销售额'].sum().unstack()print(pivot)# 4. 按销售员分组print("\n4. 销售员业绩排名:")salesperson_stats=sales.groupby('销售员').agg({'销售额':'sum','销量':'sum'}).sort_values('销售额',ascending=False)print(salesperson_stats)# 5. 按月份分组(提取月份)sales['月份']=sales['日期'].dt.month monthly_stats=sales.groupby('月份').agg({'销售额':'sum','销量':'sum'})print("\n5. 月度销售趋势:")print(monthly_stats)

8. groupby 常用聚合函数

函数说明示例
mean()平均值df.groupby('A')['B'].mean()
sum()求和df.groupby('A')['B'].sum()
count()非空值计数df.groupby('A')['B'].count()
size()行数计数(含空值)df.groupby('A').size()
min()最小值df.groupby('A')['B'].min()
max()最大值df.groupby('A')['B'].max()
std()标准差df.groupby('A')['B'].std()
var()方差df.groupby('A')['B'].var()
median()中位数df.groupby('A')['B'].median()
first()第一个值df.groupby('A')['B'].first()
last()最后一个值df.groupby('A')['B'].last()
nunique()唯一值计数df.groupby('A')['B'].nunique()

9. 总结

操作方法示例
单列分组groupby('col')df.groupby('部门')
多列分组groupby(['col1','col2'])df.groupby(['部门','绩效'])
单列聚合groupby('col')['val'].mean()df.groupby('部门')['工资'].mean()
多列聚合groupby('col')[['val1','val2']].mean()df.groupby('部门')[['工资','年龄']].mean()
多种聚合agg(['mean','sum'])df.groupby('部门')['工资'].agg(['mean','sum'])
不同列不同聚合agg({'A':'sum','B':'mean'})df.groupby('部门').agg({'工资':'sum','年龄':'mean'})
命名聚合agg(新列=('列','函数'))df.groupby('部门').agg(平均工资=('工资','mean'))
获取特定组get_group()df.groupby('部门').get_group('技术')