如何根据特定条件为在熊猫数据框中创建的组分配唯一ID。 例如:我有一个名为df的数据框,其结构如下:名称标识用户,datetime标识用户访问资源的日期/时间。
Name Datetime
Bob 26-04-2018 12:00:00
Claire 26-04-2018 12:00:00
Bob 26-04-2018 12:10:00
Bob 26-04-2018 12:30:00
Grace 27-04-2018 08:30:00
Bob 27-04-2018 09:30:00
Bob 27-04-2018 09:40:00
Bob 27-04-2018 10:00:00
Bob 27-04-2018 10:30:00
Bob 27-04-2018 11:30:00
我想为用户创建会话,以便为具有相同名称和日期时间值的用户访问资源不超过30分钟的用户分配一个唯一的会话。但是,如果用户在访问资源时显示超过30分钟的不活动状态,则该用户将在下次访问该资源时被分配一个不同的会话。
我的预期输出将如下所示。
用户Bob在2018年4月27日访问资源的时间是9.30,第二次@ 9.40,第三次@ 10.00,第四次@ 10.30->所有都与会话4关联。但是下一次用户Bob在@ 11.30上访问时差超过30分钟,因为鲍勃不活动超过30分钟,因此下一次会话将分配给他。
Name Datetime Id
Bob 26-04-2018 12:00:00 1
Claire 26-04-2018 12:00:00 2
Bob 26-04-2018 12:10:00 1
Bob 26-04-2018 12:30:00 1
Grace 27-04-2018 08:30:00 3
Bob 27-04-2018 09:30:00 4
Bob 27-04-2018 09:40:00 4
Bob 27-04-2018 10:00:00 4
Bob 27-04-2018 10:30:00 4
Bob 27-04-2018 11:30:00 5
谢谢您的帮助! 链接到上一个问题:How to compare value of second column with same values of first column in pandas dataframe?
答案 0 :(得分:2)
sort
并找到连续动作的时间差('td'
)。 cumsum
布尔序列,用于在上一个30分钟内形成连续动作组。 ngroup
标记组。
如果您不关心分组所获得的标签,可以删除分组依据前的sort_index
,但这可以确保根据原始顺序对分组进行排序。
df = df.sort_values(['Name', 'Datetime'])
df['td'] = df.Datetime.diff().mask(df.Name.ne(df.Name.shift()))
# Only calculate diff within same Name
df['Id'] = (df.sort_index()
.groupby(['Name', df['td'].gt(pd.Timedelta('30min')).cumsum()], sort=False)
.ngroup()+1)
df = df.sort_index()
td
为清楚起见
Name Datetime td Id
0 Bob 2018-04-26 12:00:00 NaT 1
1 Claire 2018-04-26 12:00:00 NaT 2
2 Bob 2018-04-26 12:10:00 00:10:00 1
3 Bob 2018-04-26 12:30:00 00:20:00 1
4 Grace 2018-04-27 08:30:00 NaT 3
5 Bob 2018-04-27 09:30:00 21:00:00 4
6 Bob 2018-04-27 09:40:00 00:10:00 4
7 Bob 2018-04-27 10:00:00 00:20:00 4
8 Bob 2018-04-27 10:30:00 00:30:00 4
9 Bob 2018-04-27 11:30:00 01:00:00 5
答案 1 :(得分:1)
您在底部的解释对理解它很有帮助。
您需要在Name
和groupID
上进行分组(不要将此groupID
与最后的Id
混淆),并致电ngroup
返回{ {1}}。最主要的是如何定义此Id
。要创建groupID
,您需要groupID
将sort_values
和Name
中的每个按升序分开。对Datetime
进行分组,并找出Name
每组(在同一Datetime
中)的连续行之间Name
中的差异。使用Name
检查大于30分钟,使用gt
获取cumsum
。 groupID
还原为原始顺序,并分配给sort_index
,如下所示:
s
接下来,将s = df.sort_values(['Name','Datetime']).groupby('Name').Datetime.diff() \
.gt(pd.Timedelta(minutes=30)).cumsum().sort_index()
和Name
与s
分组,以保留原始订单并调用sort=False
加1。
ngroup