如何用Python Pandas或Excel将长格式DataFrame按ID转为宽格式?
长格式DataFrame转宽格式的实现方法
问题背景
现有如下长格式DataFrame(示例数据):
| Info | Values |
|---|---|
| ID | 53312 |
| State | Mass |
| Address | Stackoverflowtown |
| ID | 56120 |
| State: | Bos |
| Address | Georgetown |
| Name: | James |
表格中Info列存储字段标识(如ID、State、Address等),Values列对应存储字段值,同一ID对应的State、Address等字段属于该ID,部分ID还包含Name字段。希望将其转换为以ID为索引的宽格式表格(示例如下):
| ID | State | Address | Name |
|---|---|---|---|
| 53312 | Mass | Stackoverflowtown | |
| 56120 | Bos | Georgetown | James |
尝试使用Python的Pivot功能后,结果不符合预期,各字段值分行显示、其余列空白,错误示例如下(ID 53312的转换结果):
| ID | State | Address | Name |
|---|---|---|---|
| 53312 | Null | Null | Null |
| Null | Mass | NULL | NULL |
| Null | NULL | Stackoverflowtown | NULL |
| Null | NULL | NULL | NULL |
请问如何用Python Pandas或Excel实现正确的宽格式转换?
解决方案
一、Python Pandas实现
核心思路是先为每条数据标记所属的ID分组,再进行透视转换。
- 数据预处理与转换代码
import pandas as pd # 构造示例数据 df = pd.DataFrame({ 'Info': ['ID', 'State', 'Address', 'ID', 'State:', 'Address', 'Name:'], 'Values': ['53312', 'Mass', 'Stackoverflowtown', '56120', 'Bos', 'Georgetown', 'James'] }) # 统一Info列格式:去除多余冒号 df['Info'] = df['Info'].str.replace(':', '') # 生成分组标识:每遇到一个ID,分组号递增 df['group_id'] = df['Info'].eq('ID').cumsum() # 按分组透视,整理成宽格式 result = df.pivot(index='group_id', columns='Info', values='Values').reset_index(drop=True) # 将ID设为索引(可选操作) result = result.set_index('ID') print(result)
执行后输出结果:
State Address Name ID 53312 Mass Stackoverflowtown NaN 56120 Bos Georgetown James
二、Excel实现
步骤如下:
- 添加分组列:在表格旁插入新列(如C列),命名为
分组。 - 标记分组:
- C2单元格输入
1(对应第一个ID的分组)。 - C3单元格输入公式:
=IF(A3="ID",C2+1,C2),下拉填充至所有行。
- C2单元格输入
- 统一字段名:插入D列,输入公式
=SUBSTITUTE(A2,":",""),清理Info列的冒号,下拉填充。 - 创建数据透视表:
- 选中所有数据(含分组列、清理后的字段名列),点击「插入」→「数据透视表」。
- 透视表设置:将
分组拖至「行」区域,清理后的Info字段拖至「列」区域,Values拖至「值」区域。 - 调整值字段:将汇总方式改为「最大值」或「最小值」(每个分组每个字段仅一个值,取最大/最小均可得到正确结果)。
- 最后将ID列值作为行标签,整理成目标格式即可。
内容的提问来源于stack exchange,提问作者CatDad
相关产品推荐
相关产品推荐

