蟒蛇&熊猫:获得平均排名

时间:2016-02-19 16:31:15

标签: python pandas

我有一个数据框

ID    2014-01-01    2015-01-01     2016-01-01
1     NaN           0.1            0.2                           
2     0.1           0.3            0.5
3     0.2           NaN            0.7
4     0.8           0.4            0.1

对于每个日期(col),我想获得每个id的等级。例如,在col' 2014-01-01'中,id = 4具有最大值,因此我们将等级1分配给id = 4.id = 3具有第二大值,因此我们将其赋予等级2。如果数据是NaN,则忽略它。

ID    2014-01-01    2015-01-01     2016-01-01
1     NaN           3              3                           
2     3             2              2
3     2             NaN            1
4     1             1              4

下一步是获取每个ID的平均排名。例如,id1 =(4 + 3)/ 2 = 3.5的AvgRank和id2的AvgRank =(3 + 2 + 2)/ 3 = 2.33

ID    AvgRank
1     3                         
2     2.33
3     1.5
4     2

我的算法是:

为每个id创建一个字典({str:list}) - >循环遍历所有列 - >对于每列计算排名并更新到字典中的列表

但我觉得这个简单的问题太复杂了。 有没有简单的方法来获得avgrank表?

以下是创建数据框的代码

df = pd.DataFrame({'ID':[1,2,3,4],'2014-01-01':[float('NaN'),0.1,0.2,0.8],
'2015-01-01':[0.1,0.3,float('NaN'),0.4],'2016-01-01':[0.2,0.5,0.7,0.1]})

1 个答案:

答案 0 :(得分:2)

目前还不清楚为什么你认为rank对于第二列中的第一行值应为4,但以下内容为您提供了所需内容。在这里,我们在感兴趣的列上调用rank并传递method='dense'ascending=False,使其排名正确:

In [60]:
df.ix[:, :-1].rank(method='dense', ascending=False)

Out[60]:
   2014-01-01  2015-01-01  2016-01-01
0         NaN           3           3
1           3           2           2
2           2         NaN           1
3           1           1           4

我们然后concat来自orig df的单个列和rename mean的结果以及axis=1的行方式意味着:

In [67]:
pd.concat([df['ID'], df.ix[:, :-1].rank(method='dense', ascending=False).mean(axis=1)], axis=1).rename(columns={0:'AvgRank'})

Out[67]:
   ID   AvgRank
0   1  3.000000
1   2  2.333333
2   3  1.500000
3   4  2.000000