如何在DataFrame中用透视表/Groupby实现指定数据聚合转换
数据转换需求:用透视表或Groupby实现表格重构
原始数据
给定如下DataFrame:
import pandas as pd data = { 'lifestage': ['a', 'b', 'c', 'a', 'a', 'b'], 'CC': [1, 1, 0, 1, 0, 0], 'DC': [1, 0, 1, 0, 1, 0], 'AC': [1, 1, 0, 1, 1, 1], 'CASA': [1, 0, 0, 0, 1, 0], 'Stage_1': [1, 0, 1, 0, 1, 0], 'Stage_2': [0, 1, 0, 1, 0, 0], 'Stage_3': [0, 0, 0, 1, 0, 1] } df1 = pd.DataFrame(data)
原始表格:
| lifestage | CC | DC | AC | CASA | Stage_1 | Stage_2 | Stage_3 |
|---|---|---|---|---|---|---|---|
| a | 1 | 1 | 1 | 1 | 1 | 0 | 0 |
| b | 1 | 0 | 1 | 0 | 0 | 1 | 0 |
| c | 0 | 1 | 0 | 0 | 1 | 0 | 0 |
| a | 1 | 0 | 1 | 0 | 0 | 0 | 1 |
| a | 0 | 1 | 1 | 1 | 1 | 0 | 0 |
| b | 0 | 0 | 1 | 0 | 0 | 0 | 1 |
目标输出
需要转换为以下格式:
| Lifestage | Product | Stage_1 | Stage_2 | Stage_3 |
|---|---|---|---|---|
| a | CC | 1 | 0 | 1 |
| a | DC | 2 | 0 | 0 |
| a | AC | 2 | 0 | 1 |
| a | CASA | 2 | 0 | 0 |
| b | CC | 0 | 1 | 0 |
| b | DC | 0 | 0 | 0 |
| b | AC | 0 | 1 | 1 |
| b | CASA | 0 | 0 | 0 |
| c | CC | 0 | 0 | 0 |
| c | DC | 1 | 0 | 0 |
| c | AC | 0 | 0 | 0 |
| c | CASA | 0 | 0 | 0 |
解决方案
方法一:melt + groupby 组合实现
核心逻辑是先把宽表的产品列转为长表行结构,再分组统计各Stage的次数,最后补全所有产品组合:
# 1. 重塑数据:将产品列转为行,保留分组和Stage字段 melted = df1.melt( id_vars=['lifestage', 'Stage_1', 'Stage_2', 'Stage_3'], value_vars=['CC', 'DC', 'AC', 'CASA'], var_name='Product', value_name='has_product' ) # 2. 过滤出有产品的记录,按lifestage+Product分组求和Stage字段 grouped = melted[melted['has_product'] == 1].groupby(['lifestage', 'Product'])[['Stage_1', 'Stage_2', 'Stage_3']].sum() # 3. 补全所有lifestage+Product的组合,缺失值填充0 all_combinations = pd.MultiIndex.from_product([ df1['lifestage'].unique(), ['CC', 'DC', 'AC', 'CASA'] ], names=['lifestage', 'Product']) result = grouped.reindex(all_combinations, fill_value=0).reset_index() # 4. 调整列名匹配目标格式 result = result.rename(columns={'lifestage': 'Lifestage'}) print(result)
方法二:透视表(pivot_table)实现
利用透视表的聚合能力,结合数据重塑完成转换:
# 1. 同样先重塑数据结构 melted = df1.melt( id_vars=['lifestage', 'Stage_1', 'Stage_2', 'Stage_3'], value_vars=['CC', 'DC', 'AC', 'CASA'], var_name='Product', value_name='has_product' ) # 2. 构建透视表,指定分组、聚合字段和填充值 pivot_result = pd.pivot_table( melted[melted['has_product'] == 1], index=['lifestage', 'Product'], values=['Stage_1', 'Stage_2', 'Stage_3'], aggfunc='sum', fill_value=0 ) # 3. 补全所有组合并重置索引 all_combinations = pd.MultiIndex.from_product([ df1['lifestage'].unique(), ['CC', 'DC', 'AC', 'CASA'] ], names=['lifestage', 'Product']) result = pivot_result.reindex(all_combinations, fill_value=0).reset_index().rename(columns={'lifestage': 'Lifestage'}) print(result)
关键说明
melt是核心步骤:把宽表的产品列转为长表的行,让产品成为可分组的维度。- 过滤
has_product=1:只统计用户拥有该产品的记录对应的Stage次数。 reindex补全组合:确保每个生命周期阶段下的四个产品都存在,无对应记录时显示0。
内容的提问来源于stack exchange,提问作者Sudowoodo9
相关产品推荐
相关产品推荐

