首页 > 解决方案 > Pandas:比较数据框中组内的行并创建摘要行以标记/突出显示组中的不同条目

问题描述

我有一个大约有一个熊猫数据框。1200 行,其中一些行重复多次。df 看起来像这样:

ID  Serial  Age Grade   Chem    Bio   Math  Phy
M001    2   52   37       1      1     1     1
M001    2   55   37 2     1      0     1
M001    3   51   36,5     1      1     1     0
M001    3   51   46,5     1      0     1     1
M041    2   52   36,1     1      1     0     0
M041    2   51   36,1     2      1     2     4
M041    2   52   36,1     1      1     0    
M041    2   52   36,1     1      1     1    
M010    5   58   37,4     0      1     1     3
M010    5   55   39,4     1      2     1     1
M010    5   58   37,4     1      1     1     1

数据框中的重复项应该由 ID 和 Serial 列标识,我能够做到这一点。但是,我想比较每组 ID+Serial 行以找出它们的不同之处。这有点棘手,因为有时一组中有 2 行要比较,有时每组中的行(要比较)超过 2 行。

我对一种解决方案感兴趣,我可以根据 ID 和 Serial cols 对数据框进行分组,然后比较每个组中的行。如果需要记录的两个或多个单元格之间存在差异(例如,在新行中,在冲突单元格下方带有 X 或可能以红色突出显示单元格)。生成的数据框应如下所示:

ID  Serial  Age  Grade  Chem    Bio  Math   Phy
M001    2    52   37      1      1    1      1
M001    2    55   37      2      1    0      1
M001    2    X            X           X 
M001    3    51   36,5    1      1    1      0
M001    3    51   46,5    1      0    1      1
M001    3         X              X           X
M041    2    52   36,1    1      1    0      0
M041    2    51   36,1    2      1    2      4
M041    2    52   36,1    1      1    0 
M041    2    52   36,1    1      1    1 
M041    2    X            X           X      X
M010    5    58   37,4    0      1    1      3
M010    5    55   39,4    1      2    1      1
M010    5    58   37,4    1      1    1      1
M010    5    X    X       X      X           X

有人可以帮助解决这个问题吗?

标签: pythonpandasdataframe

解决方案


ID您可以通过分组和Serial使用来创建比较标记表,并通过.groupby()获取每列的唯一条目数.nunique()。如果唯一条目数> 1,则标记为,'X'否则为空白。

最后,将新创建的比较标记表通过 .concat 连接回原始数据帧pd.concat()。排序依据IDSerial列依据.sort_values()以将相关条目重新组合在一起。

df_mark = (df.groupby(['ID', 'Serial'])
             .nunique()
             .gt(1)
             .replace({True: 'X', False: ''})
             .reset_index()
           )

(pd.concat([df, df_mark])
   .sort_values(['ID', 'Serial'])
   .reset_index(drop=True)
)

结果:

      ID  Serial Age Grade Chem Bio Math  Phy
0   M001       2  52    37    1   1    1  1.0
1   M001       2  55    37    2   1    0  1.0
2   M001       2   X          X        X     
3   M001       3  51  36,5    1   1    1  0.0
4   M001       3  51  46,5    1   0    1  1.0
5   M001       3         X        X         X
6   M010       5  58  37,4    0   1    1  3.0
7   M010       5  55  39,4    1   2    1  1.0
8   M010       5  58  37,4    1   1    1  1.0
9   M010       5   X     X    X   X         X
10  M041       2  52  36,1    1   1    0  0.0
11  M041       2  51  36,1    2   1    2  4.0
12  M041       2  52  36,1    1   1    0  NaN
13  M041       2  52  36,1    1   1    1  NaN
14  M041       2   X          X        X    X

推荐阅读