Pandas无需数值聚合的透视实现:将字符串值转为宽表格式
实现方法
pandas完全可以实现这个需求,你之前用的pivot_table是带数值聚合逻辑的,这个场景下用基础的pivot方法或者分组聚合展开即可,以下是两种常用实现方案:
方案1:分组生成序号 + pivot重塑(逻辑最清晰,性能更好)
代码实现:
import pandas as pd # 你的原始数据 d = {'Name': ['Sally', 'Sally', 'Sally', 'James', 'James', 'James'], 'Sports': ['Tennis', 'Track & field', 'Dance', 'Dance', 'MMA', 'Crosscountry']} df = pd.DataFrame(data=d) # 1. 给同一名用户下的每条运动记录生成序号 df['运动序号'] = df.groupby('Name').cumcount() + 1 # 2. 直接用pivot重塑为宽表 df_wide = df.pivot( index='Name', columns='运动序号', values='Sports' ) # 3. 重命名列符合需求,重置索引 df_wide.columns = [f'第{i}运动' for i in df_wide.columns] df_wide = df_wide.reset_index()
运行后最终输出的df_wide结构如下:
| Name | 第1运动 | 第2运动 | 第3运动 |
|---|---|---|---|
| James | Dance | MMA | Crosscountry |
| Sally | Tennis | Track & field | Dance |
如果需要调整运动的排序规则,只需要在生成序号前对df按Name和你需要的排序字段(比如运动名称)排序即可。
方案2:分组聚合列表后展开(代码更简洁)
如果不同用户参与的运动数量不一致,会自动补空值,推荐用这个方案:
df_wide = df.groupby('Name')['Sports']\ .agg(list)\ .apply(pd.Series)\ .rename(columns=lambda x: f'第{x+1}运动')\ .reset_index()
内容的提问来源于stack exchange,提问作者Wingyan Yip
相关产品推荐
相关产品推荐

