在不复制列的情况下合并多个数据帧

2024-09-26 22:50:06 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个大班级的学生分成几个部分,每个学生都有一个唯一的ID。我有一个数据框中存储的整个名册。我也有多个数据框,代表特定作业中特定部分学生的成绩。我想将所有这些信息合并到一个表示成绩册的数据框中。例如:

import pandas as pd

# Initialize roster
data = [['ab10', 'Ann Big'], ['ca9', 'Carl Ahn'], ['jb19', 'John Brown'], ['cf25', 'Carol Fox']]
roster = pd.DataFrame(data, columns = ['ID', 'Name'])

# Initialize the section grades
data = [['ab10', 95], ['ca9', 72]]
grades0 = pd.DataFrame(data, columns = ['ID', 'Exp1'])

data = [['ab10', 83], ['ca9', 97]]
grades1 = pd.DataFrame(data, columns = ['ID', 'Exp2'])

data = [['jb19', 61], ['cf25', 95]]
grades2 = pd.DataFrame(data, columns = ['ID', 'Exp1'])

# Now merge the section grades with the roster to generate final gradebook
roster = roster.merge(grades0, on = 'ID', how = 'outer')
roster = roster.merge(grades1, on = 'ID', how = 'outer')
roster = roster.merge(grades2, on = 'ID', how = 'outer')

print(roster)

此代码生成以下内容:

     ID        Name  Exp1_x  Exp2  Exp1_y
0  ab10     Ann Big    95.0  83.0     NaN
1   ca9    Carl Ahn    72.0  97.0     NaN
2  jb19  John Brown     NaN   NaN    61.0
3  cf25   Carol Fox     NaN   NaN    95.0

我不想要后缀为x和y的重复Exp1列。相反,我想要:

     ID        Name    Exp1  Exp2
0  ab10     Ann Big    95.0  83.0 
1   ca9    Carl Ahn    72.0  97.0
2  jb19  John Brown    61.0   NaN
3  cf25   Carol Fox    95.0   NaN

坡度数据帧之间不应存在重复数据(但如果存在重叠,则最好提出错误)


Tags: columns数据iddataframedatamergenan学生
2条回答

reducecombine_first

由于等级数据帧之间没有重复,因此我们可以使用reducecombine_first将所有数据帧组合在一起

from functools import reduce

reduce(pd.DataFrame.combine_first, 
      [g.set_index('ID') for g in (roster, grades0, grades1, grades2)])

      Exp1  Exp2        Name
ID                          
ab10  95.0  83.0     Ann Big
ca9   72.0  97.0    Carl Ahn
cf25  95.0   NaN   Carol Fox
jb19  61.0   NaN  John Brown

我喜欢使用pd.concat().groupby()来处理这些情况,我相信这不仅可以使结果更干净,而且还可以节省几行代码,而且可能会提高效率(因为您不会进行多次合并)。将合并行替换为:

roster = pd.concat([roster,grades0,grades1,grades2]).groupby(['ID'])['Exp1','Exp2'].sum().merge(roster,on='ID')
print(roster)

哪些产出:

    ID  Exp1  Exp2        Name
0  ab10  95.0  83.0     Ann Big
1   ca9  72.0  97.0    Carl Ahn
2  cf25  95.0   0.0   Carol Fox
3  jb19  61.0   0.0  John Brown

然后,可以将列重新排序为首选顺序。如果您喜欢将NaNs添加到0,那么可以在merge()之后添加.replace(0,np.nan)

     ID  Exp1  Exp2        Name
0  ab10  95.0  83.0     Ann Big
1   ca9  72.0  97.0    Carl Ahn
2  cf25  95.0   NaN   Carol Fox
3  jb19  61.0   NaN  John Brown

相关问题 更多 >

    热门问题