我有两个数据框,其中包含有关学生成绩和考试成绩的信息。第一个看起来像这样:
ID Test_Score Class1 Class2 Class3
0 001 85 B- A C+
1 002 78 B NaN B+
2 003 93 A B NaN
...
第二个看起来像这样:
0 1
0 Algebra A
0 Calculus_1 B
0 Calculus_2 C-
1 Algebra C+
1 Trig F
1 Trig C
1 Calculus_1 C-
...
每个数据框中的索引指的是同一位学生。因此,两个数据帧中索引为0的学生都是相同的。
我想做的是从第二个数据框中创建一个数据透视表,其中的行对应于学生(即索引),列是数学课,值是他们在每个课中取得的最高分(因为学生有可能不止一次上课)。然后,我将其连接到第一个数据帧。
我已经写了一个聚合函数,可以找到最高分。
我尝试以下操作,因为它会失败:
p = pd.pivot_table(u, columns=0, values=1, aggfunc=highest)
我得到的是单行,而不是为每个学生返回一行数据,而是包含给定班级中任何学生的最高成绩:
Algebra Trig Precalculus Calculus_1 Calculus_2
1 A A+ A+ A A
在我脑海中解决问题的方式,我只需要汇总共享索引的行,就不能确定该怎么做。
我也愿意接受完全不同的方法。
所需的输出:
ID Test_Score Class1 Class2 Class3 Algebra Trig ...
0 001 85 B- A C+ A NaN
1 002 78 B NaN B+ C+ C
2 003 93 A B NaN B B-
...
编辑: 这是我的“最高”功能的代码:
def highest(x):
q = 0
z = None
for g in x:
if qpoints(g) > q:
q = qpoints(g)
z = g
return z
其中qpoints是我已经在其他地方使用的以下函数:
def qpoints(x):
qvalue = {'W': 0,
'F': 0,
'D': 1.0,
'D+': 1.33,
'C-': 1.67,
'C': 2.0,
'C+': 2.33,
'B-': 2.67,
'B': 3.0,
'B+': 3.33,
'A-': 3.84,
'A': 4.0,
'A+': 4.0}
return qvalue[x]
答案 0 :(得分:1)
您的问题是,pivot_table
时,您需要保留第二个数据帧的索引值,有关了解请参见Comparing two files in java。因此,如果您这样做:
print (df2.reset_index().pivot_table(index='index', values=[1], columns=[0],
aggfunc= lambda x: sorted(x)[0]))
# I used my own idea of highest function
1
0 Algebra Calculus_1 Calculus_2 Trig
index
0 A B C- NaN
1 C+ C- NaN C
然后您可以this answer,例如:
df_p = df2.reset_index().pivot_table(index='index', values=[1], columns=[0],
aggfunc= lambda x: sorted(x)[0])
df_p.columns = [col[1] for col in df_p.columns]
new_df = df1.join(df_p)
print (new_df)
ID Test_Score Class1 Class2 Class3 Algebra Calculus_1 Calculus_2 Trig
0 001 85 B- A C+ A B C- NaN
1 002 78 B NaN B+ C+ C- NaN C
2 003 93 A B NaN NaN NaN NaN NaN
答案 1 :(得分:0)
这就是您想要的。但是,使用数据透视表时,您将不允许使用重复的列名,因此,对同一用户进行两次Trig操作将导致错误。
因此,在将重复的Trig值重命名为Trig2之后,联接/枢轴效果很好。
df = pd.DataFrame({'ID':['001','002','003'],'Test_Score':[85,78,93],'Class1':['B-','B','A'],'Class2':['A','','B'],'Class3':['C+','B+','',]})
df2 = pd.DataFrame({0:['Algebra','Calculus_1','Calculus_2','Algebra','Trig','Trig2','Calculus_1'],1:['A','B','C-','C+','F','C','C-']}, index=[0,0,0,1,1,1,1])
df.join(df2.pivot(columns=0, values=1))
ID Test_Score Class1 Class2 Class3 Algebra Calculus_1 Calculus_2 Trig Trig2
0 001 85 B- A C+ A B C- NaN NaN
1 002 78 B B+ C+ C- NaN F C
2 003 93 A B NaN NaN NaN NaN NaN