按日期对 pandas df 中的组进行排序和排名

BAC*_*C83 3 python sorting group-by ranking pandas

从以下类型的数据框中,我希望能够id按日期对字段进行排序和排名:

df = pd.DataFrame({
'id':[1, 1, 2, 3, 3, 4, 5, 6,6,6,7,7], 
'value':[.01, .4, .2, .3, .11, .21, .4, .01, 3, .5, .8, .9],
'date':['10/01/2017 15:45:00','05/01/2017 15:56:00',
        '11/01/2017 15:22:00','06/01/2017 11:02:00','05/01/2017 09:37:00',
        '05/01/2017 09:55:00','05/01/2017 10:08:00','03/02/2017 08:55:00',
        '03/02/2017 09:15:00','03/02/2017 09:31:00','09/01/2017 15:42:00',
        '19/01/2017 16:34:00']})
Run Code Online (Sandbox Code Playgroud)

id根据日期有效排名或索引。

我用过

df.groupby('id')['date'].min()
Run Code Online (Sandbox Code Playgroud)

这允许我提取第一个日期(虽然我不知道如何使用它来过滤掉行),但我可能并不总是需要第一个日期 - 有时它会是第二个或第三个日期,所以我需要生成一个新的列,带有日期索引 - 结果将如下所示:

在此输入图像描述

关于这种排序/排名/标签有什么想法吗?

编辑

我最初的模型忽略了一个非常普遍的问题。

由于可能有一些id并行执行多个测试,因此它们显示在数据库中的多行中,并具有匹配的日期(date对应于它们的记录时间)。这些应该被算作相同的日期,而不是增加 date_rank:我已经生成了一个模型,并进行了更新date_rank以演示其外观:

df = pd.DataFrame({
'id':[1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6,6,6,7,7], 
'value':[.01, .4, .5, .7, .77, .1,.2, 0.3, .11, .21, .4, .01, 3, .5, .8, .9, .1],
'date':['10/01/2017 15:45:00','10/01/2017 15:45:00','05/01/2017 15:56:00',
        '11/01/2017 15:22:00','11/01/2017 15:22:00','06/01/2017 11:02:00','05/01/2017 09:37:00','05/01/2017 09:37:00','05/01/2017 09:55:00',
        '05/01/2017 09:55:00','05/01/2017 10:08:00','05/01/2017 10:09:00','03/02/2017 08:55:00',
        '03/02/2017 09:15:00','03/02/2017 09:31:00','09/01/2017 15:42:00',
        '19/01/2017 16:34:00']})
Run Code Online (Sandbox Code Playgroud)

计数器可以承受这个:

在此输入图像描述

Nag*_*ran 5

您可以尝试按降序对日期值进行排序并聚合“id”组值

@praveen的逻辑非常简单,通过扩展逻辑,您可以使用类别的astype将值转换为类别,并可以检索该类别的代码(键'),但它与您的预期输出有点不同

df1 = df.sort_values(['id', 'date'], ascending=[True, False])
df1['date_rank'] =df1.groupby(['id']).apply(lambda x: x['date'].astype('category',ordered=False).cat.codes+1).values
Run Code Online (Sandbox Code Playgroud)

出去:

                 date   id  value   date_rank
0   10/01/2017 15:45:00 1   0.01    2
1   10/01/2017 15:45:00 1   0.40    2
2   05/01/2017 15:56:00 1   0.50    1
3   11/01/2017 15:22:00 2   0.70    1
4   11/01/2017 15:22:00 2   0.77    1
5   06/01/2017 11:02:00 3   0.10    2
6   05/01/2017 09:37:00 3   0.20    1
7   05/01/2017 09:37:00 3   0.30    1
8   05/01/2017 09:55:00 4   0.11    1
9   05/01/2017 09:55:00 4   0.21    1
11  05/01/2017 10:09:00 5   0.01    2
10  05/01/2017 10:08:00 5   0.40    1
14  03/02/2017 09:31:00 6   0.80    3
13  03/02/2017 09:15:00 6   0.50    2
12  03/02/2017 08:55:00 6   3.00    1
16  19/01/2017 16:34:00 7   0.10    2
15  09/01/2017 15:42:00 7   0.90    1
Run Code Online (Sandbox Code Playgroud)

但为了获得准确的输出,这里我使用了字典和反转字典键来提取值

df1 = df.sort_values(['id', 'date'], ascending=[True, False])
df1['date_rank'] = df1.groupby(['id'])['date'].transform(lambda x: list(map(lambda y: dict(map(reversed, dict(enumerate(x.unique())).items()))[y]+1,x)) )
Run Code Online (Sandbox Code Playgroud)

出去:

                date    id  value   date_rank
0   10/01/2017 15:45:00 1   0.01    1
1   10/01/2017 15:45:00 1   0.40    1
2   05/01/2017 15:56:00 1   0.50    2
3   11/01/2017 15:22:00 2   0.70    1
4   11/01/2017 15:22:00 2   0.77    1
5   06/01/2017 11:02:00 3   0.10    1
6   05/01/2017 09:37:00 3   0.20    2
7   05/01/2017 09:37:00 3   0.30    2
8   05/01/2017 09:55:00 4   0.11    1
9   05/01/2017 09:55:00 4   0.21    1
11  05/01/2017 10:09:00 5   0.01    1
10  05/01/2017 10:08:00 5   0.40    2
14  03/02/2017 09:31:00 6   0.80    1
13  03/02/2017 09:15:00 6   0.50    2
12  03/02/2017 08:55:00 6   3.00    3
16  19/01/2017 16:34:00 7   0.10    1
15  09/01/2017 15:42:00 7   0.90    2
Run Code Online (Sandbox Code Playgroud)