如何使用Pandas或Numpy获取用户会话的时间序列?
我有一些数据,记录了一系列用户的登录和登出时间。
输入数据:
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 个回答
你最好的办法是使用像 strptime 这样的工具来转换时间:
import time
t = time.strptime("5:24pm", "%H:%M%p")
>>> t.tm_hour
5
>>> t.tm_min
24
这样一来,你就可以把所有的时间都调整到同一个小时,比如说,你想要的那样。
看看这个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]>
我找到了一种看起来效果不错的方法:
假设我们可以把登录和登出数据转化成两个以时间为索引的数据表:
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')