如何用Pandas将df2匹配多行转为df1的新增列?
解决方案:将多行列转置后合并到主DataFrame
你需要先把df2中同一Course Offering Code+User Id组合下的多行记录转成宽表结构,再和df1合并,具体步骤如下:
步骤1:为每组记录添加行序号
给每个用户+课程组合内的作业记录添加自增序号,用于后续转列时区分不同作业:
import pandas as pd # 构造示例数据 df1 = pd.DataFrame({ 'Course Offering Code': ['001', '001'], 'User Id': [1, 2] }) df2 = pd.DataFrame({ 'Course Offering Code': ['001']*8, 'User Id': [1]*4 + [2]*4, 'Assignment': ['A01', 'A02', 'A03', 'A04']*2, 'grade%': [65, 85, 95, 64, 87, 86, 82, 90] }) # 添加组内序号 df2['idx'] = df2.groupby(['Course Offering Code', 'User Id']).cumcount()
步骤2:将df2转置为宽表
通过pivot把同一组内的多行作业数据转成多列:
df2_wide = df2.pivot( index=['Course Offering Code', 'User Id'], columns='idx', values=['Assignment', 'grade%'] ) # 调整列名格式(比如Assignment_0、grade%_0) df2_wide.columns = [f'{col[0]}_{col[1]}' for col in df2_wide.columns] df2_wide = df2_wide.reset_index()
步骤3:合并到df1
将转置后的宽表和df1合并(因为df1的行就是每个用户+课程组合,直接用df2_wide也能得到目标结果,用merge是为了兼容df1有额外列的情况):
desired_df = pd.merge(df1, df2_wide, on=['Course Offering Code', 'User Id'], how='left')
如果需要把列名后缀改成你示例中的x/y/z/a格式,可以添加以下映射代码:
# 可选:将数字序号替换为字母后缀 letter_map = {0: 'x', 1: 'y', 2: 'z', 3: 'a'} df2_wide.columns = [f'{col.split("_")[0]}_{letter_map[int(col.split("_")[1])]}' if '_' in col else col for col in df2_wide.columns]
为什么之前的merge不生效?
你之前用的pd.merge(df1, df2, ...)会把匹配的行进行行堆叠,导致每个用户+课程组合对应多行记录,而不是把作业转成列。必须先将df2转成宽表,再合并才能得到目标结构。
内容的提问来源于stack exchange,提问作者Kevin
相关产品推荐
相关产品推荐

