如何使用Pandas或Numpy获取用户会话的时间序列?

2 投票
3 回答
1431 浏览
提问于 2025-04-18 03:04

我有一些数据,记录了一系列用户的登录和登出时间。

输入数据:

        Login        Logout
User_1  10:25AM      6:01PM
User_2  8:58AM       5:12PM
User_3  9:23AM       1:35PM
User_3  3:10PM       4:49PM

我想知道在某个时间段内,有多少用户是在线的(比如说,每小时)。

我还想把这个数据和我在Pandas中其他相同时间段的数据联系起来,比如说在那个时间段内有多少个“Foo”事件。

期望的输出:

          Num Logged In   Foo Event Count
9:00AM                1                11
10:00AM               2                17
11:00AM               3                28
12:00PM               3                26
1:00PM                3                22
2:00PM                2                15
3:00PM                2                15
4:00PM                3                22
5:00PM                2                13

最简单的情况是,我可以得到在早上10点正登录的用户数量,这样就能有一个有用的开始。如果我想把数据重新采样到按天计算,那我就需要更聪明一点,看看比如说在早上9点到下午5点之间,最多同时在线的用户数量,或者平均同时在线的用户数量。

显然,我可以写一些简单的Python代码,给定我在Pandas中重新采样的时间段,来得到我需要的数据序列,但我想知道在Pandas中有没有什么技巧可以帮助我,或者在Numpy中可以做些什么,因为我想把这个应用到比较大的数据集上(比如几百个用户,几千天,每个用户每天有多次登录和登出)。

3 个回答

0

你最好的办法是使用像 strptime 这样的工具来转换时间:

import time
t = time.strptime("5:24pm", "%H:%M%p")
>>> t.tm_hour
5
>>> t.tm_min
24

这样一来,你就可以把所有的时间都调整到同一个小时,比如说,你想要的那样。

1

看看这个Arrow模块 - 它提供了非常通用的日期时间对象,并且有很多高级的方法可以使用。

范围和跨度

你可以获取任何单位的时间跨度:

>>> arrow.utcnow().span('hour')
(<Arrow [2013-05-07T05:00:00+00:00]>, <Arrow [2013-05-07T05:59:59.999999+00:00]>)

或者你也可以直接获取最小值和最大值:

>>> arrow.utcnow().floor('hour')
<Arrow [2013-05-07T05:00:00+00:00]>

>>> arrow.utcnow().ceil('hour')
<Arrow [2013-05-07T05:59:59.999999+00:00]>
2

我找到了一种看起来效果不错的方法:

假设我们可以把登录和登出数据转化成两个以时间为索引的数据表:

Login    UserLogin
-------- ---------
8:58AM   User_2    
9:23AM   User_3    
10:25AM  User_1    
3:10PM   User_3    

Logout   UserLogout
-------- ----------
1:35PM   User_3
4:49PM   User_3
5:12PM   User_2
6:01PM   User_1

接着,我们可以在每个表中添加一个额外的列:登录用1表示,登出用-1表示:

login['AvailabilityDelta'] = 1
logout['AvailabilityDelta'] = -1

然后我们可以对这两个表进行外连接,并把连接后产生的空值用0填充:

events = login.join(logout, how='outer')
events.fillna(value=0, inplace=True)

在新连接的“事件”数据表上,我们再创建一个“可用性变化”列,这个列是“登录”和“登出”列的总和(就是我们之前添加的1和-1):

events['AvailabilityDelta'] = events.Login + events.Logout

最后,我们可以通过对“可用性变化”列进行累加,来创建一个“可用性”列。这样就得到了我们最初想要的“登录人数”数据:

events['Availability'] = events.AvailabilityDelta.cumsum()

到这个时候,添加额外信息或者创建时间序列数据就变得简单了,比如:

ts = events.resample('1H', how='mean', fill_method='ffill')

撰写回答