本文目录导读:

我来为你详细介绍使用Pandas进行数据分组的完整案例。
基础数据准备
import pandas as pd
import numpy as np
# 创建示例数据
data = {
'部门': ['销售部', '技术部', '销售部', '技术部', '市场部',
'市场部', '销售部', '技术部', '市场部', '销售部'],
'姓名': ['张三', '李四', '王五', '赵六', '孙七',
'周八', '吴九', '郑十', '冯十一', '陈十二'],
'销售额': [5000, 8000, 6000, 9000, 7000,
5500, 7500, 8500, 6200, 6800],
'年龄': [25, 30, 28, 35, 32, 27, 29, 33, 26, 31],
'入职年份': [2020, 2019, 2021, 2018, 2020,
2022, 2019, 2020, 2021, 2022]
}
df = pd.DataFrame(data)
print("原始数据:")
print(df)
基本分组操作
单列分组
# 按部门分组并计算平均值
dept_stats = df.groupby('部门')['销售额'].mean()
print("\n各部门平均销售额:")
print(dept_stats)
# 多列分组统计
dept_age_stats = df.groupby('部门')[['销售额', '年龄']].mean()
print("\n各部门销售额和年龄平均值:")
print(dept_age_stats)
多列分组
# 按部门和入职年份分组
multi_group = df.groupby(['部门', '入职年份']).agg({
'销售额': 'sum',
'年龄': 'mean',
'姓名': 'count'
}).rename(columns={'姓名': '人数'})
print("\n按部门和入职年份分组统计:")
print(multi_group)
常用聚合函数
# 多种聚合方式
dept_full_stats = df.groupby('部门')['销售额'].agg([
'sum', # 总和
'mean', # 平均值
'std', # 标准差
'min', # 最小值
'max', # 最大值
'count', # 计数
'median' # 中位数
]).round(2)
print("\n各部门销售额详细统计:")
print(dept_full_stats)
# 使用自定义聚合函数
def range_calc(x):
return x.max() - x.min()
dept_range = df.groupby('部门')['销售额'].agg([
'sum',
range_calc, # 自定义函数
lambda x: x.max() - x.min() # lambda函数
]).rename(columns={'sum': '总和', 'range_calc': '极差', '<lambda>': '极差(λ)'})
print("\n自定义聚合:")
print(dept_range)
分组后的转换和过滤
# 计算每个部门销售额占比
df['部门销售额占比'] = df.groupby('部门')['销售额'].transform(
lambda x: x / x.sum() * 100
)
print("\n添加部门占比列:")
print(df)
# 使用transform进行标准化
df['销售额Z分数'] = df.groupby('部门')['销售额'].transform(
lambda x: (x - x.mean()) / x.std()
)
print("\n销售额Z分数(部门内标准化):")
print(df[['部门', '姓名', '销售额', '销售额Z分数']])
# 过滤分组数据
# 保留至少销售总额大于20000的部门
high_perform_depts = df.groupby('部门').filter(
lambda x: x['销售额'].sum() > 20000
)
print("\n高绩效部门(销售额>20000):")
print(high_perform_depts)
进阶分组操作
# 使用apply进行复杂操作
dept_rank = df.groupby('部门')['销售额'].apply(
lambda x: x.rank(ascending=False)
).reset_index(name='部门排名')
print("\n部门内销售额排名:")
print(dept_rank)
# 饼图
import matplotlib.pyplot as plt
# 分组后的可视化
dept_sum = df.groupby('部门')['销售额'].sum()
plt.figure(figsize=(10, 4))
plt.subplot(1, 2, 1)
dept_sum.plot(kind='bar', color=['skyblue', 'lightgreen', 'salmon'])'各部门销售额汇总')
plt.ylabel('销售额')
plt.xticks(rotation=45)
plt.subplot(1, 2, 2)
dept_avg = df.groupby('部门')['年龄'].mean()
dept_avg.plot(kind='bar', color=['gold', 'lightblue', 'pink'])'各部门平均年龄')
plt.ylabel('年龄')
plt.xticks(rotation=45)
plt.tight_layout()
plt.show()
# 分组后排序
dept_sort = df.groupby('部门').agg({
'销售额': 'sum',
'年龄': 'mean'
}).sort_values('销售额', ascending=False)
print("\n按销售额降序排列的部门统计:")
print(dept_sort)
# 分组后取Top N
top_2_in_each_dept = df.groupby('部门').apply(
lambda x: x.nlargest(2, '销售额')
).reset_index(drop=True)
print("\n每个部门销售额前2名:")
print(top_2_in_each_dept)
实际应用案例
# 销售绩效分析
sales_analysis = df.groupby('部门').agg({
'销售额': ['sum', 'mean', 'count', 'std'],
'年龄': ['mean', 'min', 'max']
})
# 扁平化列名
sales_analysis.columns = [
f'{col[0]}_{col[1]}' for col in sales_analysis.columns
]
sales_analysis = sales_analysis.reset_index()
print("\n销售绩效分析报告:")
print(sales_analysis)
# 创建透视表
pivot_table = pd.pivot_table(
df,
values='销售额',
index='部门',
columns='入职年份',
aggfunc='sum',
fill_value=0
)
print("\n销售额透视表(部门×入职年份):")
print(pivot_table)
# 分组后检查缺失值
df_with_nan = df.copy()
df_with_nan.loc[df_with_nan['部门'] == '销售部', '销售额'] = np.nan
# 按部门检查缺失值
nan_check = df_with_nan.groupby('部门')['销售额'].apply(
lambda x: x.isna().sum()
)
print("\n各部门销售额缺失值数量:")
print(nan_check)
性能优化技巧
import time
# 大数据集测试
big_df = pd.DataFrame({
'group': np.random.choice(['A', 'B', 'C', 'D', 'E'], 100000),
'value': np.random.randn(100000)
})
# 方法1: 使用groupby
start_time = time.time()
result1 = big_df.groupby('group')['value'].agg(['sum', 'mean', 'std'])
method1_time = time.time() - start_time
print(f"方法1 (groupby) 耗时: {method1_time:.4f} 秒")
# 方法2: 使用pivot_table
start_time = time.time()
result2 = big_df.pivot_table(
values='value',
index='group',
aggfunc=['sum', 'mean', 'std']
)
method2_time = time.time() - start_time
print(f"方法2 (pivot_table) 耗时: {method2_time:.4f} 秒")
# 方法3: 使用for循环(不推荐)
start_time = time.time()
result3 = {}
for group in big_df['group'].unique():
subset = big_df[big_df['group'] == group]['value']
result3[group] = {
'sum': subset.sum(),
'mean': subset.mean(),
'std': subset.std()
}
method3_time = time.time() - start_time
print(f"方法3 (for循环) 耗时: {method3_time:.4f} 秒")
Pandas分组操作的核心要点:
- 基本语法:
df.groupby('column')['target'].agg(function) - 常用聚合函数:sum, mean, count, min, max, std, var
- 高级操作:transform, filter, apply
- 性能优化:优先使用内置聚合函数,避免循环操作
这些案例涵盖了Pandas分组的常见场景,你可以根据实际需求选择合适的操作方法。