如何用Pivot/Melt重塑Pandas DataFrame?实现指定列结构转换
问题描述
我有一个包含Series Name、Country Name以及2000 [YR2000]、2001 [YR2001]……2018 [YR2018]年份列的Pandas DataFrame。其中Series Name为待分析变量(如'PBI'、'Surface Area'等),该列存在重复值(每个国家对应一条某变量的记录)。
原DataFrame结构示例:
| Series Name | Country Name | 2000 [YR2000] | 2001 [YR2001] |
|---|---|---|---|
| Superficie (kilómetros cuadrados) | Estados Unidos | 9632030 | 9632030 |
| Superficie (kilómetros cuadrados) | Unión Europea | 4384964,995 | 4384984,995 |
| Superficie (kilómetros cuadrados) | Japón | 377800 | 377880 |
希望将DataFrame重塑为以下结构:
- 列:
Country Name、Year以及所有Series Name的唯一值 Year列:填充每个国家对应的2000至2018年- 各
Series Name列:存储对应国家和年份的数值
目标结构示例:
| Country Name | Year | Superficie (kilómetros cuadrados) |
|---|---|---|
| Estados Unidos | 2000 | 9632030 |
| Estados Unidos | 2001 | 9632030 |
| Unión Europea | 2000 | 4384964,995 |
| Unión Europea | 2001 | 4384984,995 |
| Japón | 2000 | 377800 |
| Japón | 2001 | 377880 |
尝试过以下代码但未得到预期结果:
indicadores_clean_pv = pd.melt(indicadores_clean, id_vars=['Country Name'], var_name='Año')
indicadores_clean_pv.melt(id_vars='Country Name', var_name='Year').groupby(['Country Name','Year']).agg({'Series Name':'first'}).reset_index()
无法将Series Name的取值设为列,请求实现所需的结构转换。
解决方案
你需要分三步完成数据重塑,核心是先熔解年份列,再将变量名转成列:
import pandas as pd # 1. 熔解年份列:保留Series Name和Country Name作为标识,将所有年份列转成键值对 melted = pd.melt( indicadores_clean, id_vars=['Series Name', 'Country Name'], # 必须保留这两个标识列 var_name='Year', value_name='Value' ) # 2. 提取纯年份数字:去掉原列名的[YRxxxx]后缀,转成整数类型 melted['Year'] = melted['Year'].str.extract(r'(\d{4})').astype(int) # 3. 将Series Name转成列:用pivot_table实现宽表转换,处理可能的重复记录 result = melted.pivot_table( index=['Country Name', 'Year'], columns='Series Name', values='Value', aggfunc='first' # 若有重复记录取第一个值,可按需替换为mean/sum等 ).reset_index()
关键说明
- 第一步的修正:你之前的
melt只保留了Country Name,漏掉了Series Name,导致无法关联变量和对应数值,这是核心问题。 - 年份提取:正则
(\d{4})精准匹配4位年份数字,转成整数后更便于后续时间序列分析。 - pivot_table的作用:自动将每个
Series Name的唯一值转为单独列,同时用aggfunc处理可能的重复数据(比如同一国家同一年份同一变量有多条记录)。
运行后得到的DataFrame完全符合你的需求:每个国家对应所有年份的记录,每个分析变量作为独立列存储对应数值。
内容的提问来源于stack exchange,提问作者alter_k
相关产品推荐
相关产品推荐

