数据透视表按索引聚合

时间:2019-05-28 19:33:40

标签: python pandas pivot-table

我有两个数据框,其中包含有关学生成绩和考试成绩的信息。第一个看起来像这样:

     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]

2 个答案:

答案 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