如何使用pandas的groupby函数生成按客户分组的服务收入宽表?
问题描述
现有长格式DataFrame如下:
| 客户 | 服务类型 | 收入 |
|---|---|---|
| foo. | A. | 25. |
| foo. | B. | 50. |
| foo. | C | 15. |
| bar | A | 25. |
| bar. | b | 10. |
需要转换为宽格式,每行对应一个客户,各列对应不同服务类型的收入,缺失项填充为0,目标结果如下:
| 客户 | 服务类型A收入 | 服务类型B收入 | 服务类型C收入 |
|---|---|---|---|
| foo. | 25 | 50 | 15 |
| bar | 25 | 10 | 0 |
要求使用pandas的groupby函数实现转换。
解决方案
步骤1:数据预处理
首先要统一客户名称和服务类型的格式,避免因大小写、末尾标点导致分组错误:
- 客户名称:去掉末尾的
.(比如bar.转为bar) - 服务类型:去掉末尾的
.并转为大写(比如A.→A,b→B)
步骤2:分组与格式转换
通过groupby按客户和服务类型分组后求和(确保同一客户同一服务的收入合并),再用unstack将服务类型转为列,最后填充缺失值为0并调整列名。
完整代码示例
import pandas as pd # 构造原始数据 df = pd.DataFrame({ '客户': ['foo.', 'foo.', 'foo.', 'bar', 'bar.'], '服务类型': ['A.', 'B.', 'C', 'A', 'b'], '收入': [25., 50., 15., 25., 10.] }) # 数据清洗:统一格式 df['客户'] = df['客户'].str.rstrip('.') # 去掉客户名称末尾的点 df['服务类型'] = df['服务类型'].str.rstrip('.').str.upper() # 统一服务类型格式 # 使用groupby+unstack实现宽表转换 wide_df = df.groupby(['客户', '服务类型'])['收入'].sum() \ .unstack(fill_value=0) \ .rename(columns=lambda x: f'服务类型{x}收入') \ .reset_index() print(wide_df)
代码说明
groupby(['客户', '服务类型'])['收入'].sum():按客户和服务类型分组,对收入求和,确保同一分组的收入合并。unstack(fill_value=0):将服务类型从行索引转为列,缺失的服务类型自动填充0。rename(columns=lambda x: f'服务类型{x}收入'):将列名调整为目标格式(比如A→服务类型A收入)。reset_index():将客户从索引转回普通列。
内容的提问来源于stack exchange,提问作者snakshak12
相关产品推荐
相关产品推荐

