如何在Pandas中实现列重排与编码,将多组名称-百分比列转换为透视表结构
如何在Pandas中实现列重排与编码,将多组名称-百分比列转换为透视表结构
你遇到的这个需求其实是典型的宽表转长表再转宽表的操作,我帮你梳理下具体的实现步骤,亲测有效~
先还原你的原始数据结构(方便复现):
import pandas as pd df = pd.DataFrame({ 'ID': [1, 2], 'comp_1_name': ['name_1', 'name_3'], 'comp_1_percentage': [13, 15], 'comp_2_name': ['name_2', 'name_1'], 'comp_2_percentage': [33, 46] # 这里可以扩展到comp_3到comp_6的列,逻辑完全一致 })
下面是具体的转换步骤:
第一步:把多组名称-百分比列转成“长格式”
我们可以用pd.melt()来拆分这些成对的列,关键是通过id_vars保留ID列,然后给其他列分组。这里用正则匹配自动识别comp_X的分组标识:# 拆分列名,提取分组标识(比如comp_1、comp_2)和类型(name/percentage) df_melted = df.melt(id_vars='ID', var_name='col', value_name='value') df_melted['group'] = df_melted['col'].str.extract(r'(comp_\d+)') df_melted['type'] = df_melted['col'].str.extract(r'_(name|percentage)$') # 将同一组的name和percentage转成并列的列 df_long = df_melted.pivot_table( index=['ID', 'group'], columns='type', values='value', aggfunc='first' ).reset_index() df_long = df_long.drop(columns='group') # 分组标识完成使命,可以移除第二步:将长表转成目标的宽表结构
现在用pivot把名称作为列,对应百分比作为值,最后把缺失的位置填充为0:df_result = df_long.pivot( index='ID', columns='name', values='percentage' ).fillna(0).reset_index() df_result.columns.name = None # 去掉列索引的冗余名称
运行后你就能得到想要的结果:
ID name_1 name_2 name_3 0 1 13.0 33.0 0.0 1 2 46.0 0.0 15.0
另外还有一种更简洁的写法,利用Pandas专门处理这类重复前缀列的wide_to_long函数,代码更紧凑:
# 直接拆分带前缀的列,指定名称和百分比的stubnames df_wide = pd.wide_to_long( df, stubnames=['comp', 'comp'], i='ID', j='num', sep='_', suffix=r'\w+' ) df_wide.columns = ['name', 'percentage'] # 透视并填充缺失值 df_result = df_wide.reset_index().pivot( index='ID', columns='name', values='percentage' ).fillna(0).reset_index() df_result.columns.name = None
至于你之前尝试的转置(.T)没用的原因:转置只是简单交换行列,没有处理名称和百分比的对应关系,必须先把每一组的名称和百分比配对关联,再重新透视才能得到目标结构哦~
备注:内容来源于stack exchange,提问作者Alessandro Togni
相关产品推荐
相关产品推荐

