pandas-python中Unstack列操作:实现DataFrame逆透视转换为指定格式
Pandas 长表转宽表实现方案
你需要的是长表转宽表的透视操作,你之前尝试的pd.melt是宽表转长表的方法,和需求方向相反;pd.unstack需要配合多层索引使用,直接调用无法得到预期结果。
以下是两种可直接运行的实现方案:
方案1:透视表方法(支持处理同姓名同课程的多状态)
如果同一个人同一门课存在多条状态记录,可以自定义聚合规则,比如合并多个状态为逗号分隔字符串:
import pandas as pd # 原始数据 a = pd.DataFrame( columns=['Name','Title','Status'], data=[ ['John','Course1','Finished'], ['Mike','Course2','Accepted'], ['Jim','Course1','Accepted'], ['Jhonny','Course3','Rejected'], ['Jhonny','Course3','Accepted'] ] ) # 生成宽表,同组合多状态合并为逗号分隔字符串 result = a.pivot_table( index='Name', columns='Title', values='Status', aggfunc=lambda x: ','.join(x) ).reset_index().rename_axis(columns=None)
运行后result的输出格式如下:
| Name | Course1 | Course2 | Course3 |
|---|---|---|---|
| Jim | Accepted | ||
| Jhonny | Rejected,Accepted | ||
| John | Finished | ||
| Mike | Accepted |
方案2:set_index + unstack 方法(适合无重复Name+Title组合的场景)
如果你的数据中同一个人同一门课只会有一条记录,可以用该方法实现:
# 先按Name、Title去重,保留最后一条有效记录 a_dedup = a.drop_duplicates(subset=['Name', 'Title'], keep='last') # 设两层索引后unstack课程列 result = a_dedup.set_index(['Name', 'Title'])['Status'].unstack(fill_value=pd.NA).reset_index().rename_axis(columns=None)
如果不需要空值填充,可以去掉fill_value=pd.NA参数,空值会默认填充NaN。
内容的提问来源于stack exchange,提问作者alb
相关产品推荐
相关产品推荐

