本文目录导读:

我来详细介绍Python中使用Pandas进行数据分组转换的几种常见方法。
基础分组与转换
准备示例数据
import pandas as pd
import numpy as np
# 创建示例数据
data = {
'部门': ['技术部', '技术部', '技术部', '市场部', '市场部', '市场部', '销售部', '销售部'],
'员工': ['张三', '李四', '王五', '赵六', '钱七', '孙八', '周九', '吴十'],
'薪资': [15000, 18000, 20000, 12000, 14000, 16000, 13000, 17000],
'工龄': [3, 5, 7, 2, 4, 6, 3, 5]
}
df = pd.DataFrame(data)
print("原始数据:")
print(df)
groupby + transform() 方法
计算组内统计量
# 计算每个部门薪资的平均值
df['部门平均薪资'] = df.groupby('部门')['薪资'].transform('mean')
# 计算每个部门薪资的最大值
df['部门最高薪资'] = df.groupby('部门')['薪资'].transform('max')
# 计算薪资占部门百分比
df['薪资占比'] = df.groupby('部门')['薪资'].transform(lambda x: x / x.sum() * 100)
print("转换后的数据:")
print(df)
填充组内缺失值
# 创建包含缺失值的数据
df_missing = df.copy()
df_missing.loc[0, '薪资'] = np.nan
df_missing.loc[3, '薪资'] = np.nan
# 用组内平均值填充缺失值
df_missing['薪资'] = df_missing.groupby('部门')['薪资'].transform(lambda x: x.fillna(x.mean()))
print("填充缺失值后的数据:")
print(df_missing)
自定义转换函数
def normalize_salary(group):
"""对组内薪资进行标准化"""
return (group - group.mean()) / group.std()
def rank_within_group(group):
"""计算组内排名"""
return group.rank(ascending=False)
# 应用自定义函数
df['标准化薪资'] = df.groupby('部门')['薪资'].transform(normalize_salary)
df['组内排名'] = df.groupby('部门')['薪资'].transform(rank_within_group)
print("自定义转换后的数据:")
print(df[['部门', '员工', '薪资', '标准化薪资', '组内排名']])
多列分组转换
# 多列分组求平均值
df['部门_工龄平均薪资'] = df.groupby(['部门', '工龄'])['薪资'].transform('mean')
# 多列分组计算累积值
df['累计薪资'] = df.groupby('部门')['薪资'].transform('cumsum')
# 多列分组后求差值
df['薪资提升'] = df.groupby('部门')['薪资'].transform('diff')
print("多列分组转换:")
print(df[['部门', '员工', '薪资', '工龄', '部门_工龄平均薪资', '累计薪资', '薪资提升']])
实际应用案例
案例1:销售数据分析
# 创建销售数据
sales_data = {
'地区': ['华北', '华北', '华北', '华东', '华东', '华东', '华南', '华南'],
'月份': ['1月', '2月', '3月', '1月', '2月', '3月', '1月', '2月'],
'销售额': [100000, 120000, 150000, 200000, 180000, 220000, 160000, 140000],
'目标额': [110000, 130000, 140000, 190000, 200000, 210000, 150000, 160000]
}
sales_df = pd.DataFrame(sales_data)
# 计算各地区销售额与目标的差异
sales_df['达标率'] = (sales_df['销售额'] / sales_df['目标额']) * 100
# 计算各地区月度增长率
sales_df['月度增长率'] = sales_df.groupby('地区')['销售额'].transform(lambda x: x.pct_change() * 100)
print("销售数据分析:")
print(sales_df)
案例2:学生成绩分析
# 创建学生成绩数据
student_data = {
'班级': ['A班', 'A班', 'A班', 'B班', 'B班', 'B班', 'C班', 'C班'],
'学生': ['小明', '小红', '小刚', '小华', '小李', '小美', '小强', '小丽'],
'语文': [85, 92, 78, 88, 95, 72, 80, 90],
'数学': [90, 85, 95, 78, 88, 92, 85, 95],
'英语': [88, 90, 82, 85, 92, 78, 88, 86]
}
student_df = pd.DataFrame(student_data)
# 计算总分
student_df['总分'] = student_df[['语文', '数学', '英语']].sum(axis=1)
# 计算班级内排名
student_df['班级排名'] = student_df.groupby('班级')['总分'].rank(ascending=False, method='min')
# 计算各科成绩与班级平均分的差异
for subject in ['语文', '数学', '英语']:
col_name = f'{subject}与班级均分差'
student_df[col_name] = student_df[subject] - student_df.groupby('班级')[subject].transform('mean')
print("学生成绩分析:")
print(student_df)
高级分组转换技巧
使用agg()函数同时处理多列
# 按部门分组,同时对多个列应用不同转换
transformed = df.groupby('部门').agg({
'薪资': ['mean', 'std', 'min', 'max'],
'工龄': 'mean'
})
print("多列聚合结果:")
print(transformed)
条件分组转换
# 根据条件创建新分组
df['薪资等级'] = pd.cut(df['薪资'], bins=[0, 15000, 18000, float('inf')],
labels=['低薪', '中薪', '高薪'])
# 按新分组进行转换
df['组内百分比'] = df.groupby('薪资等级')['薪资'].transform(
lambda x: x / x.sum() * 100
)
print("条件分组转换:")
print(df[['部门', '员工', '薪资', '薪资等级', '组内百分比']])
性能优化建议
import time
# 创建大数据集
large_data = pd.DataFrame({
'group': np.random.choice(['A', 'B', 'C', 'D'], 100000),
'value': np.random.randn(100000)
})
# 方法1: 使用transform(推荐)
start = time.time()
result1 = large_data.groupby('group')['value'].transform('mean')
print(f"transform方法耗时: {time.time() - start:.4f}秒")
# 方法2: 使用merge(较慢)
start = time.time()
group_means = large_data.groupby('group')['value'].mean().rename('mean')
result2 = large_data.merge(group_means, left_on='group', right_index=True)
print(f"merge方法耗时: {time.time() - start:.4f}秒")
# 验证结果是否相同
print(f"结果是否一致: {all(result1 == result2['mean'])}")
Pandas的分组转换提供了强大的数据处理能力:
- transform():最常用的分组转换方法,保持原DataFrame的形状
- 自定义函数:可以定义复杂的转换逻辑
- 实际应用:适合销售分析、成绩统计等场景
- 性能优化:transform通常比merge方法更快
掌握这些技巧可以大大提高数据处理的效率和灵活性。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播