大熊猫为每列添加新的“排名”列

时间:2019-03-08 19:34:35

标签: python pandas

我有一个这样的df(实际df有450万行,每列23列):

group  feature  col1  col2  col3
g1     f1       1     10    100
g1     f1       11    9     1000
g1     f2       0     8     200
g2     f1       2     7     330
g2     f2       3     7     331
g2     f3       1     7     100
g3     f1       1     6     101
g3     f1       5     9     100
g3     f1       1     8     100

我想为我的df中的每个col添加两个新的“等级” col。我将以不同的方式评估不同的列,例如求和,均值,最大值等。为便于说明,我将问题分为以下两个独立的问题。

已建议我here使用.loc而不使用groupby,但是任何可行的解决方案都可以。我已经尝试过但都没有成功(请参阅here

排名第一的col将在每个组中的col1,col2和col3 中的值上对每个要素进行排名。

在中间阶段,它看起来像这样:

group  feature  col1  col1_sum  col1_rank  col2  col2_avg  col2_rank  col3 col3_max  col3_rank
g1     f1       1     12        1          10    9.5       1          100  1000      1
g1     f1       11                         9                          1000           
g1     f2       0     0         2          8     8         2          200  200       2
g2     f1       2     2         2          7     7         1          330  330       2
g2     f2       3     3         1          7     7         1          331  331       1
g2     f3       1     1         3          7     7         1          100  100       3
g3     f1       1     7         1          6     7.67      1          101  101       1
g3     f1       5                          9                          100            
g3     f1       1                          8                          100            

它将输出:

group  feature  col1_rank  col2_rank  col3_rank
g1     f1       1          1          1
g1     f2       2          2          2
g2     f1       2          1          2
g2     f2       1          1          1
g2     f3       3          1          3
g3     f1       1          1          1

第二个等级col将按col1,col2和col3中的值相对于所有其他组对每个组进行排名。

在中间阶段,它看起来像这样:

group  feature  col1  col1_sum  col1_rank  col2  col2_avg  col2_rank  col3 col3_max  col3_rank
g1     f1       1     12        1          10    9.5       1          100  1000      1
g1     f1       11                         9                          1000           
g2     f1       2     2         3          7     7         3          330  330       2
g3     f1       1     7         2          6     7.67      2          101  101       3
g3     f1       5                          9                          100            
g3     f1       1                          8                          100            

g1     f2       0     0         2          8     8         1          200  200       2
g2     f2       3     3         1          7     7         2          331  331       1

g2     f3       1     1         1          7     7         1          100  100       1

它将输出:

group  feature  col1_rank  col2_rank  col3_rank
g1     f1       1          1          1
g2     f1       3          3          2
g3     f1       2          2          3
g1     f2       2          1          2
g2     f2       1          2          1
g2     f3       1          1          1

1 个答案:

答案 0 :(得分:1)

我会在groupby上使用['group', 'feature']来产生一个中间数据帧,其中包含sum,avg和max列(而不是排名),然后在groupby上再次使用group只是产生排名。

中间数据框:

df2 = pd.concat([
    df.iloc[:,[0,1,2]].groupby(['group', 'feature']).sum(),
    df.iloc[:,[0,1,3]].groupby(['group', 'feature']).mean(),
    df.iloc[:,[0,1,4]].groupby(['group', 'feature']).max()
    ], axis=1)

中间数据帧为:

               col1      col2  col3
group feature                      
g1    f1         12  9.500000  1000
      f2          0  8.000000   200
g2    f1          2  7.000000   330
      f2          3  7.000000   331
      f3          1  7.000000   100
g3    f1          7  7.666667   101

现在是最后一个数据帧:

df3 = df2.groupby('group').rank(method='min', ascending=False).reset_index()

最终会给出:

  group feature  col1  col2  col3
0    g1      f1   1.0   1.0   1.0
1    g1      f2   2.0   2.0   2.0
2    g2      f1   2.0   1.0   2.0
3    g2      f2   1.0   1.0   1.0
4    g2      f3   3.0   1.0   3.0
5    g3      f1   1.0   1.0   1.0

对于问题的第二部分,我只是更改中间数据帧的索引,并在对'feature'进行分组之后计算排名:

dfx4 = dfx.reset_index().set_index(['feature', 'group']
                                   ).sort_index().groupby('feature').rank(
                                   method='min', ascending=False
                                   ).reset_index()

给出:

  feature group  col1  col2  col3
0      f1    g1   1.0   1.0   1.0
1      f1    g2   3.0   3.0   2.0
2      f1    g3   2.0   2.0   3.0
3      f2    g1   2.0   1.0   2.0
4      f2    g2   1.0   2.0   1.0
5      f3    g2   1.0   1.0   1.0