You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 04:21:46