Python Pandas Groupby:如何将分组后的层级数据行转列?
将Pandas长表按分组转为带序号列的宽表
我来帮你搞定这个长表转宽表的需求,这在Pandas里可以通过分组+透视的组合操作实现,还能顺便统计每组的行数。咱们一步步拆解来做:
步骤1:准备示例数据(如果你的数据已经存在,这步可以跳过)
先把你给出的示例数据转换成DataFrame:
import pandas as pd # 构造原始长表数据 df = pd.DataFrame({ 'name': ['jane', 'jane', 'dan', 'bill', 'bill', 'bill'], 'gender': ['female', 'female', 'male', 'male', 'male', 'male'], 'year': [2011, 2015, 2009, 2001, 2003, 2000], 'city': ['Detroit', 'Chicago', 'Lexington', 'New York', 'Buffalo', 'San Francisco'] })
步骤2:按组排序并添加序号
观察你的目标宽表,每组的year是按升序排列的(比如bill的year是2000→2001→2003),所以先按name分组后对year升序排序,再给每组内的行添加从1开始的序号,方便后续生成带编号的列名:
# 按name分组,组内按year升序排序 df_sorted = df.sort_values(['name', 'year']) # 给每个name组内的行添加序号(从1开始) df_sorted['seq'] = df_sorted.groupby('name').cumcount() + 1
步骤3:透视转换为宽表
用pivot方法把长表转成宽表,以name和gender作为索引,序号seq作为列,同时把year和city作为值;之后还要把多级列名合并成year1、city1这种格式:
# 透视生成宽表 wide_df = df_sorted.pivot( index=['name', 'gender'], columns='seq', values=['year', 'city'] ) # 合并多级列名,比如('year', 1) → 'year1' wide_df.columns = [f'{col[0]}{col[1]}' for col in wide_df.columns] # 把索引还原成普通列 wide_df = wide_df.reset_index()
步骤4:添加city total列
统计每个name对应的行数,也就是city total,然后合并到宽表中:
# 计算每个name的记录数 city_total = df.groupby('name').size().rename('city total') # 合并到宽表 wide_df = wide_df.merge(city_total, on='name')
步骤5:优化显示(可选)
把空值替换成空字符串,让输出更贴近你想要的格式:
wide_df = wide_df.fillna('')
最终结果
运行完所有代码后,打印wide_df就能得到你想要的宽表:
name gender year1 city1 year2 city2 year3 city3 city total 0 bill male 2000 San Francisco 2001 New York 2003 Buffalo 3 1 dan male 2009 Lexington 1 2 jane female 2011 Detroit 2015 Chicago 2
内容的提问来源于stack exchange,提问作者user7939708
相关产品推荐
相关产品推荐

