如何将DataFrame从长格式转换为带分组列的宽格式?
Pandas长表转宽表:生成带序号后缀的扁平化列名
需求是把长格式的DataFrame按group字段分组转为宽格式,要求最终的列名是single_id_1、country_1这种带组内序号后缀的形式,而非默认的多层索引结构。
原始数据
import pandas as pd df = pd.DataFrame( [ {'group': 'group-009297534', 'single_id': 'single-011900051', 'country': 'ESP', 'name': '00000911'}, {'group': 'group-009297534', 'single_id': 'single-000000821', 'country': 'USA', 'name': '00001054'}, {'group': 'group-009280053', 'single_id': 'single-000000002', 'country': 'HUN', 'name': '00000496'}, {'group': 'group-009280053', 'single_id': 'single-000000014', 'country': 'HUN', 'name': '00000795'}, {'group': 'group-009245039', 'single_id': 'single-000001258', 'country': 'NOR', 'name': '00000527'}, {'group': 'group-009245039', 'single_id': 'single-000000669', 'country': 'TWN', 'name': '00000535'} ] )
原方法的问题
你尝试用cumcount生成组内索引后做pivot,得到的是多层索引列,不符合预期的扁平化列名格式:
df['idx'] = df.groupby('group').cumcount() df.pivot(index='group', columns='idx')
优雅的实现方案
直接对pivot(或unstack)后的多层列名进行合并,一步得到目标格式:
# 生成组内序号(从1开始,若要从0开始去掉+1即可) df['idx'] = df.groupby('group').cumcount() + 1 # 转宽并合并列名 wide_df = df.set_index(['group', 'idx']).unstack(level='idx') wide_df.columns = [f'{col[0]}_{col[1]}' for col in wide_df.columns] # 可选:把group从索引转回普通列 wide_df = wide_df.reset_index()
如果想要更简洁的写法,也可以用pivot后直接处理列名:
df['idx'] = df.groupby('group').cumcount() + 1 wide_df = df.pivot(index='group', columns='idx') wide_df.columns = [f'{feat}_{num}' for feat, num in wide_df.columns] wide_df = wide_df.reset_index()
这样得到的结果列就是single_id_1、single_id_2、country_1、country_2这种扁平化的命名,完全符合需求。如果组内元素数量不固定,这个方法也能自动适配,不管每组有1个还是多个元素,都会生成对应的带序号后缀的列。
内容的提问来源于stack exchange,提问作者HedgeHog
相关产品推荐
相关产品推荐

