Python 在不复制列的情况下合并多个数据帧
我有一个大班级的学生分成几个部分,每个学生都有一个唯一的ID。我有一个数据框中存储的整个名册。我也有多个数据框,代表特定作业中特定部分学生的成绩。我想将所有这些信息合并到一个表示成绩册的数据框中。例如:Python 在不复制列的情况下合并多个数据帧,python,pandas,dataframe,Python,Pandas,Dataframe,我有一个大班级的学生分成几个部分,每个学生都有一个唯一的ID。我有一个数据框中存储的整个名册。我也有多个数据框,代表特定作业中特定部分学生的成绩。我想将所有这些信息合并到一个表示成绩册的数据框中。例如: import pandas as pd # Initialize roster data = [['ab10', 'Ann Big'], ['ca9', 'Carl Ahn'], ['jb19', 'John Brown'], ['cf25', 'Carol Fox']] roster = p
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
等级数据帧之间不应存在重复数据(但如果存在重叠,则引发错误将是一种良好的做法)。我喜欢将
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
添加到0s,则可以在合并()之后添加。替换(0,np.nan)
先用合并
减少
由于等级数据帧之间不存在重复,因此我们可以使用compose\u first
将所有数据帧组合在一起
from functools import reduce
reduce(pd.DataFrame.combine_first,
[g.set_index('ID') for g in (roster, grades0, grades1, grades2)])
谢谢,但是如果我事先不知道作业的名称怎么办?我需要避免硬编码['Exp1','Exp2']。首先组合正是我需要的!非常感谢。@Melissa很乐意帮助!
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