如何将指定结构的Pandas DataFrame转置变形为目标格式?
解决DataFrame按年份列重组的问题
首先明确你的需求:把按年份行存储的物理成绩,转成以年份为列、同组成绩逐行对齐的结构,长度不一致的行留空。
先看你的原始数据和目标结构:
原始DataFrame
import pandas as pd df = pd.DataFrame(columns=["AC_YEAR","Physics"],data=[[2010,8],[2010,9],[2011,7],[2010,3],[2011,4]])
目标结构
df2 = pd.DataFrame(columns=[2010,2011],data=[[8,7],[9,4],[3,]])
你原来的代码问题分析
你用循环+pd.concat的思路方向是对的,但有两个关键错误:
- 没有将concat结果赋值回df2:每次循环里的
pd.concat只是生成了新的DataFrame,但没有保存到df2变量中,最后df2还是初始的空DataFrame - join参数用了"inner":
inner会只保留两个DataFrame索引重叠的行,2010有3条数据,2011只有2条,用inner会丢掉2010的第三条数据,不符合你的目标需求
正确解法
这里提供两种简洁的实现方式:
方法一:分组提取后拼接(直观易懂)
先分别提取每个年份的成绩,重置索引后按列拼接,长度不一致的行自动留空(pandas里用NaN表示空值,和你目标里的[3,]效果一致):
# 提取各年份的Physics列,重置索引保证行对齐 year_2010 = df[df["AC_YEAR"] == 2010]["Physics"].reset_index(drop=True) year_2011 = df[df["AC_YEAR"] == 2011]["Physics"].reset_index(drop=True) # 按列拼接,设置列名为年份 df2 = pd.concat([year_2010, year_2011], axis=1) df2.columns = [2010, 2011]
方法二:用pivot透视(更简洁的pandas风格)
先给每个年份组内的行添加序号,再通过透视把年份转成列:
# 给每个AC_YEAR分组添加组内行号 df['row_id'] = df.groupby('AC_YEAR').cumcount() # 透视转换:行号为索引,年份为列,值为Physics成绩 df2 = df.pivot(index='row_id', columns='AC_YEAR', values='Physics').reset_index(drop=True)
运行后得到的df2就是你想要的结构,空值会自动填充为NaN,和目标一致。
内容的提问来源于stack exchange,提问作者MTT
相关产品推荐
相关产品推荐

