Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/354.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在不复制列的情况下合并多个数据帧_Python_Pandas_Dataframe - Fatal编程技术网

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

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

我有一个大班级的学生分成几个部分,每个学生都有一个唯一的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

等级数据帧之间不应存在重复数据(但如果存在重叠,则引发错误将是一种良好的做法)。

我喜欢将
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