本文目录导读:

我来详细介绍如何使用Pandas进行数据分组和重聚合的各种方法。
基础数据准备
import pandas as pd
import numpy as np
# 创建示例数据
data = {
'部门': ['技术部', '技术部', '销售部', '销售部', '市场部', '市场部', '技术部', '销售部'],
'城市': ['北京', '上海', '北京', '上海', '北京', '上海', '广州', '广州'],
'姓名': ['张三', '李四', '王五', '赵六', '钱七', '孙八', '周九', '吴十'],
'年龄': [25, 28, 32, 27, 30, 26, 35, 29],
'工资': [8000, 12000, 15000, 10000, 9000, 11000, 13000, 14000],
'入职年份': [2020, 2019, 2018, 2021, 2020, 2022, 2017, 2020]
}
df = pd.DataFrame(data)
print("原始数据:")
print(df)
基础分组操作
1 单列分组
# 按单列分组并计算平均值
grouped_single = df.groupby('部门')['工资'].mean()
print("\n按部门分组,平均工资:")
print(grouped_single)
# 分组后计算多个统计量
grouped_stats = df.groupby('部门')['工资'].agg(['mean', 'sum', 'min', 'max', 'count'])
print("\n按部门分组,工资统计:")
print(grouped_stats)
2 多列分组
# 按多个列分组
grouped_multi = df.groupby(['部门', '城市'])['工资'].mean()
print("\n按部门和城市分组,平均工资:")
print(grouped_multi)
# 重新设置索引
grouped_multi_reset = grouped_multi.reset_index()
print("\n重置索引:")
print(grouped_multi_reset)
聚合函数详解
1 多种聚合方式
# 对不同列使用不同的聚合函数
agg_result = df.groupby('部门').agg({
'工资': ['mean', 'sum', 'std'],
'年龄': ['mean', 'min', 'max'],
'入职年份': ['min', 'max']
})
print("\n多列多聚合函数:")
print(agg_result)
# 自定义列名
agg_named = df.groupby('部门').agg(
平均工资=('工资', 'mean'),
总工资=('工资', 'sum'),
平均年龄=('年龄', 'mean'),
最大年龄=('年龄', 'max')
)
print("\n自定义列名:")
print(agg_named)
2 自定义聚合函数
# 自定义聚合函数
def salary_range(x):
return x.max() - x.min()
def top_salary_count(x):
return (x > 12000).sum()
custom_agg = df.groupby('部门')['工资'].agg([
('工资范围', salary_range),
('高薪人数', top_salary_count),
('中位数', lambda x: x.median())
])
print("\n自定义聚合函数:")
print(custom_agg)
高级分组操作
1 transform操作
# transform - 保持原始形状
df['部门平均工资'] = df.groupby('部门')['工资'].transform('mean')
df['部门内排名'] = df.groupby('部门')['工资'].transform('rank')
print("\ntransform操作:")
print(df[['部门', '姓名', '工资', '部门平均工资', '部门内排名']])
2 filter筛选
# 筛选出平均工资大于12000的部门
filtered = df.groupby('部门').filter(lambda x: x['工资'].mean() > 12000)
print("\n平均工资>12000的部门数据:")
print(filtered)
3 apply高级应用
# 对每个组应用自定义函数
def group_summary(group):
return pd.Series({
'人数': len(group),
'总工资': group['工资'].sum(),
'平均工资': group['工资'].mean(),
'年龄范围': group['年龄'].max() - group['年龄'].min()
})
summary = df.groupby('部门').apply(group_summary)
print("\n分组汇总信息:")
print(summary)
实际案例分析
1 销售数据分析
# 创建销售数据
sales_data = pd.DataFrame({
'日期': pd.date_range('2024-01-01', periods=20, freq='D'),
'产品': np.random.choice(['A', 'B', 'C'], 20),
'区域': np.random.choice(['东区', '西区', '南区'], 20),
'销售额': np.random.randint(1000, 10000, 20),
'数量': np.random.randint(10, 100, 20)
})
print("销售数据:")
print(sales_data.head())
# 按产品和区域分组分析
analysis = sales_data.groupby(['产品', '区域']).agg({
'销售额': ['sum', 'mean', 'std'],
'数量': ['sum', 'mean'],
'日期': ['min', 'max']
}).round(2)
print("\n销售分析:")
print(analysis)
2 员工数据多维度分析
# 多维度分析
multi_analysis = df.groupby(['部门', '城市']).agg({
'工资': ['mean', 'sum'],
'年龄': 'mean',
'姓名': 'count'
}).round(2)
# 重命名列
multi_analysis.columns = ['平均工资', '总工资', '平均年龄', '人数']
print("\n多维度员工分析:")
print(multi_analysis)
# 创建数据透视表
pivot_table = pd.pivot_table(
df,
values='工资',
index='部门',
columns='城市',
aggfunc=['mean', 'sum'],
fill_value=0
)
print("\n数据透视表:")
print(pivot_table)
性能优化技巧
import time
# 大数据集测试
large_data = pd.DataFrame({
'group': np.random.choice(['A', 'B', 'C', 'D', 'E'], 1000000),
'value1': np.random.randn(1000000),
'value2': np.random.randn(1000000)
})
# 方法1: 直接groupby
start = time.time()
result1 = large_data.groupby('group')['value1'].mean()
print(f"方法1耗时: {time.time() - start:.3f}秒")
# 方法2: 使用category类型
large_data['group'] = large_data['group'].astype('category')
start = time.time()
result2 = large_data.groupby('group')['value1'].mean()
print(f"方法2(优化)耗时: {time.time() - start:.3f}秒")
常见问题解决方案
# 处理缺失值
df_with_na = df.copy()
df_with_na.loc[0, '工资'] = np.nan
print("\n包含缺失值的数据:")
print(df_with_na)
# 方法1: 分组前填充
result_ffill = df_with_na.groupby('部门')['工资'].transform(lambda x: x.fillna(x.mean()))
print("\n填充缺失值后的结果:")
print(result_ffill)
# 方法2: 分组后忽略缺失值
result_na_ignore = df_with_na.groupby('部门')['工资'].mean(skipna=True)
print("\n忽略缺失值的分组计算:")
print(result_na_ignore)
Pandas分组重聚合的关键要点:
- 基本方法:使用
groupby()配合agg()、transform()、filter()、apply() - 聚合函数:内置函数(mean, sum等)+ 自定义函数
- 多级分组:支持多列分组和分层索引
- 性能优化:使用category类型、向量化操作
这些方法可以满足大部分数据分组聚合的需求,从简单的统计到复杂的数据分析任务都能很好处理。