本文目录导读:

我来详细介绍使用Pandas进行数据分组遍历的几种常见方法。
基础分组遍历
创建示例数据
import pandas as pd
import numpy as np
# 创建示例数据
data = {
'部门': ['销售部', '技术部', '销售部', '技术部', '人事部', '销售部'],
'姓名': ['张三', '李四', '王五', '赵六', '孙七', '周八'],
'年龄': [25, 30, 28, 35, 27, 32],
'薪资': [8000, 15000, 9000, 18000, 7000, 10000],
'入职年份': [2019, 2018, 2020, 2017, 2021, 2019]
}
df = pd.DataFrame(data)
print("原始数据:")
print(df)
使用groupby()进行分组遍历
方法1:直接遍历分组对象
# 按部门分组
grouped = df.groupby('部门')
# 遍历每个组
for name, group in grouped:
print(f"部门:{name}")
print(f"组内数据:")
print(group)
print(f"组内人数:{len(group)}")
print("-" * 50)
方法2:使用apply()函数
# 定义处理函数
def process_group(group):
avg_salary = group['薪资'].mean()
max_age = group['年龄'].max()
print(f"部门:{group['部门'].iloc[0]}")
print(f"平均薪资:{avg_salary}")
print(f"最大年龄:{max_age}")
print(f"员工列表:{', '.join(group['姓名'])}")
print("-" * 50)
return group
# 应用函数
df.groupby('部门').apply(process_group)
方法3:多列分组遍历
# 按部门和入职年份分组
grouped_multi = df.groupby(['部门', '入职年份'])
print("多列分组遍历:")
for (dept, year), group in grouped_multi:
print(f"部门:{dept}, 入职年份:{year}")
print(group)
print("-" * 50)
分组后的统计操作
# 遍历并计算统计信息
print("部门统计信息:")
for name, group in df.groupby('部门'):
stats = {
'人数': len(group),
'平均年龄': group['年龄'].mean(),
'平均薪资': group['薪资'].mean(),
'最高薪资': group['薪资'].max(),
'最低薪资': group['薪资'].min()
}
print(f"部门:{name}")
for key, value in stats.items():
print(f" {key}:{value:.2f}" if isinstance(value, float) else f" {key}:{value}")
print()
分组后修改数据
# 遍历分组并修改数据
df_modified = df.copy()
for name, group in df_modified.groupby('部门'):
# 计算该部门的平均薪资
avg_salary = group['薪资'].mean()
# 为组内每个员工添加薪资等级
for idx in group.index:
if df_modified.loc[idx, '薪资'] > avg_salary:
df_modified.loc[idx, '薪资等级'] = '高'
else:
df_modified.loc[idx, '薪资等级'] = '低'
print("修改后的数据:")
print(df_modified)
使用iteritems()遍历分组统计结果
# 计算各部门的平均薪资,然后遍历
dept_avg = df.groupby('部门')['薪资'].mean()
print("各部门平均薪资遍历:")
for dept, avg_salary in dept_avg.iteritems():
print(f"{dept}:平均薪资 {avg_salary:.0f} 元")
实际应用案例
案例1:员工绩效分析
# 模拟更多数据
np.random.seed(42)
data_large = {
'部门': np.random.choice(['销售部', '技术部', '人事部', '财务部'], 100),
'姓名': [f'员工{i}' for i in range(100)],
'销售额': np.random.randint(10000, 100000, 100),
'KPI评分': np.random.uniform(60, 100, 100)
}
df_performance = pd.DataFrame(data_large)
# 按部门分析绩效
print("部门绩效分析:")
for dept, group in df_performance.groupby('部门'):
top_3 = group.nlargest(3, 'KPI评分')
print(f"\n{dept}:")
print(f" 平均销售额:{group['销售额'].mean():.0f}")
print(f" 平均KPI评分:{group['KPI评分'].mean():.1f}")
print(f" KPI前3名:")
for _, emp in top_3.iterrows():
print(f" {emp['姓名']} - KPI:{emp['KPI评分']:.1f}, 销售额:{emp['销售额']}")
案例2:数据清洗和异常检测
# 创建包含异常数据的数据集
data_messy = {
'类别': ['A', 'A', 'B', 'B', 'C', 'C'],
'数值': [10, 25, 15, 150, 8, 12],
'日期': pd.date_range('2024-01-01', periods=6)
}
df_messy = pd.DataFrame(data_messy)
# 按类别检测异常值
print("异常值检测:")
for name, group in df_messy.groupby('类别'):
mean = group['数值'].mean()
std = group['数值'].std()
threshold = 2 * std # 2倍标准差
outliers = group[abs(group['数值'] - mean) > threshold]
if len(outliers) > 0:
print(f"{name}类存在异常值:")
for _, row in outliers.iterrows():
print(f" 日期:{row['日期'].date()}, 数值:{row['数值']}")
else:
print(f"{name}类数据正常:均值为{mean:.1f},标准差为{std:.1f}")
性能优化建议
# 对于大数据集,使用agg()方法更高效
def fast_group_operation(df):
"""快速分组统计"""
result = df.groupby('部门').agg({
'薪资': ['mean', 'max', 'min'],
'年龄': 'mean',
'姓名': 'count'
})
return result
# 使用transform()进行分组内操作
def add_dept_percentile(df):
"""添加部门内的薪资百分位"""
df['薪资百分位'] = df.groupby('部门')['薪资'].transform(
lambda x: x.rank(pct=True)
)
return df
print("快速分组统计结果:")
print(fast_group_operation(df))
print("\n添加百分位后的数据:")
print(add_dept_percentile(df))
Pandas分组遍历的主要方法:
- 直接遍历:
for name, group in df.groupby('column') - apply()方法:处理复杂逻辑
- transform()方法:高效的分组内计算
- agg()方法:快速聚合统计
选择建议:
- 数据量小(<1万行):
groupby遍历 - 数据量大:优先使用
agg()或transform() - 需要复杂逻辑:使用
apply() - 实时交互:使用
groupby对象直接操作
这些方法可以满足大多数数据分组分析的需求。