使用Pandas简化重复的DataFrame结构
Pandas简化重复的DataFrame结构
嘿,刚接触Python Pandas确实会被这种数据结构转换搞懵,我来帮你理清楚!你想要的其实是把宽格式的DataFrame转成窄格式——简单说就是把年份相关的列拆成“年份+对应数值”的行,每个国家对应每一年的数据。Pandas里有个专门的函数melt()正好干这个事,比手动折腾行索引靠谱多了。
先模拟一下你现在的DataFrame结构(方便你对照):
import pandas as pd # 假设你的原始数据长这样 df = pd.DataFrame({ '国家': ['中国', '美国', '日本'], 'STATUS_YR_2020': [100, 200, 150], 'STATUS_YR_2021': [120, 220, 160], 'STATUS_YR_2022': [130, 230, 170] })
解决方案:用melt()一键转换
直接用melt函数指定要保留的固定列、新列的名称就行:
# 核心转换代码 transformed_df = df.melt( id_vars=['国家'], # 保持不变的列(这里就是国家列) var_name='年份', # 原来的年份列名会放到这个新列里 value_name='数值' # 原来的单元格数值对应到这个新列 ) # 如果想把"STATUS_YR_"前缀去掉,只保留年份数字,加这一步: transformed_df['年份'] = transformed_df['年份'].str.replace('STATUS_YR_', '')
转换后你会得到这样的结果:
| 国家 | 年份 | 数值 |
|---|---|---|
| 中国 | 2020 | 100 |
| 美国 | 2020 | 200 |
| 日本 | 2020 | 150 |
| 中国 | 2021 | 120 |
| 美国 | 2021 | 220 |
| ... | ... | ... |
补充说明
- 如果你的原始年份列名直接是
2020、2021这种(没有STATUS_YR_前缀),那更简单,去掉后面的字符串替换步骤就行。 - 你之前试的移动行、重置索引为啥越搞越乱?因为那些操作是调整行的顺序或索引,不是针对这种“宽表转窄表”的结构化转换,
melt是Pandas专门为这类场景设计的工具,比手动操作高效且不易出错。
备注:内容来源于stack exchange,提问作者Patrick




