如何使用Pandas将多列宽格式数据转长格式并新增来源分组列
Pandas宽表转长表:拆分多列组并新增分组标识
问题描述
现有如下Pandas DataFrame:
name a1 b1 c1 d1 a2 b2 c2 d2 joe x y x y z e e f lily x o x y z o e f john o y x q z f e q
需要将其转换为长格式,使行数翻倍,新增new_col标识数据来源分组:a1、b1、c1、d1对应group1,a2、b2、c2、d2对应group2,目标结果如下:
name a1 b1 c1 d1 new_col joe x y x y group1 lily x o x y group1 john o y x q group1 joe z e e f group2 lily z o e f group2 john z f e q group2
尝试使用pd.melt仅能处理单组列对,无法完成多列组的转换,示例代码及结果如下:
import pandas as pd pd.melt(df, id_vars = 'name', var_name = 'a_var', value_vars = ['a1', 'a2'])
运行结果:
name a_var value joe a1 x lily a1 x john a1 o joe a2 z lily a2 z john a2 z
解决方案
方法1:拆分DataFrame后合并(直观易懂)
分别提取两组列的数据,重命名第二组的列名以匹配第一组,添加分组标识后合并:
import pandas as pd # 提取group1数据并新增分组列 group1 = df[['name', 'a1', 'b1', 'c1', 'd1']].copy() group1['new_col'] = 'group1' # 提取group2数据,重命名列名并新增分组列 group2 = df[['name', 'a2', 'b2', 'c2', 'd2']].copy() group2.columns = ['name', 'a1', 'b1', 'c1', 'd1'] group2['new_col'] = 'group2' # 合并两组数据 result = pd.concat([group1, group2], ignore_index=True)
方法2:通用化处理(适配多分组场景)
如果后续存在更多类似分组(如a3-d3、a4-d4等),可使用以下通用方法:
import pandas as pd # 1. 将所有非name列转为长格式 melted = df.melt(id_vars='name', var_name='col', value_name='value') # 2. 从列名中拆分出前缀(a/b/c/d)和分组编号(1/2) melted[['prefix', 'group_num']] = melted['col'].str.extract(r'([a-d])(\d)') # 3. 转回宽格式,按name和分组编号聚合 pivoted = melted.pivot_table(index=['name', 'group_num'], columns='prefix', values='value', aggfunc='first').reset_index() # 4. 整理列名和分组标识 pivoted.columns = ['name', 'group_num', 'a1', 'b1', 'c1', 'd1'] pivoted['new_col'] = 'group' + pivoted['group_num'] result = pivoted.drop('group_num', axis=1)[['name', 'a1', 'b1', 'c1', 'd1', 'new_col']]
结果验证
两种方法均可得到目标格式的DataFrame,执行print(result)即可查看最终结果。
内容的提问来源于stack exchange,提问作者fastlanes
相关产品推荐
相关产品推荐

