Python 基于熊猫中的时间戳创建交互会话
我正在尝试定义在不同的移动使用会话中使用了哪些应用程序。基本上,会话是由一个用户执行的一系列操作 单个用户在很小的时间范围内完成(也称为会话增量)。换句话说,如果在前一个事件的5分钟内没有发生交互 交互时,用户的会话被视为已关闭。下一个 交互被视为一个单独的会话。我想知道数据集中有多少移动会话。另外,我想知道在每个会话中启动了哪些应用程序。 我的数据框中的所有行都有时间戳。 以下是数据集中的一个示例:Python 基于熊猫中的时间戳创建交互会话,python,pandas,time-series,Python,Pandas,Time Series,我正在尝试定义在不同的移动使用会话中使用了哪些应用程序。基本上,会话是由一个用户执行的一系列操作 单个用户在很小的时间范围内完成(也称为会话增量)。换句话说,如果在前一个事件的5分钟内没有发生交互 交互时,用户的会话被视为已关闭。下一个 交互被视为一个单独的会话。我想知道数据集中有多少移动会话。另外,我想知道在每个会话中启动了哪些应用程序。 我的数据框中的所有行都有时间戳。 以下是数据集中的一个示例: timestamp App 6784 201
timestamp App
6784 2018-04-08 14:31:29.209 Google
6785 2018-04-08 14:58:42.875 Google
6786 2018-04-08 18:18:04.757 Chrome
6787 2018-04-08 21:08:41.368 Google
6788 2018-04-11 10:53:10.744 Google
6789 2018-04-14 19:54:37.441 Google
6790 2018-04-14 19:54:59.833 Google
6791 2018-04-14 19:55:10.844 YouTube
6792 2018-04-14 19:55:34.486 Google
6793 2018-04-14 20:23:00.315 Google
6794 2018-04-15 08:23:44.873 Google
6795 2018-04-15 08:24:07.257 Google
6796 2018-04-16 16:42:35.538 Google
6797 2018-04-16 16:42:48.351 Google
6798 2018-04-17 08:10:54.734 Google
6799 2018-04-17 08:13:28.855 Google
6800 2018-04-17 08:16:49.408 Google
6801 2018-04-17 08:18:55.049 Google
6802 2018-04-17 08:21:04.201 Google
6803 2018-04-17 08:26:14.254 Google
这是期望的输出:
timestamp App SessionID
6784 2018-04-08 14:31:29.209 Google 1
6785 2018-04-08 14:58:42.875 Google 2
6786 2018-04-08 18:18:04.757 Chrome 3
6787 2018-04-08 21:08:41.368 Google 4
6788 2018-04-11 10:53:10.744 Google 5
6789 2018-04-14 19:54:37.441 Google 6
6790 2018-04-14 19:54:59.833 Google 6
6791 2018-04-14 19:55:10.844 YouTube 6
6792 2018-04-14 19:55:34.486 Google 6
6793 2018-04-14 20:23:00.315 Google 7
6794 2018-04-15 08:23:44.873 Google 8
6795 2018-04-15 08:24:07.257 Google 8
6796 2018-04-16 16:42:35.538 Google 9
6797 2018-04-16 16:42:48.351 Google 9
6798 2018-04-17 08:10:54.734 Google 10
6799 2018-04-17 08:13:28.855 Google 10
6800 2018-04-17 08:16:49.408 Google 10
6801 2018-04-17 08:18:55.049 Google 10
6802 2018-04-17 08:21:04.201 Google 10
6803 2018-04-17 08:26:14.254 Google 11
我想你想要
.shift
+.cumsum()
+1
是因为差异的第一行始终是NaT
,比较的结果为False
,否则将始终从0开始SessionID
import pandas as pd
df['SessionID'] = (df.timestamp-df.timestamp.shift(1) > pd.Timedelta(5, 'm')).cumsum()+1
timestamp App SessionID
6784 2018-04-08 14:31:29.209 Google 1
6785 2018-04-08 14:58:42.875 Google 2
6786 2018-04-08 18:18:04.757 Chrome 3
6787 2018-04-08 21:08:41.368 Google 4
6788 2018-04-11 10:53:10.744 Google 5
6789 2018-04-14 19:54:37.441 Google 6
6790 2018-04-14 19:54:59.833 Google 6
6791 2018-04-14 19:55:10.844 YouTube 6
6792 2018-04-14 19:55:34.486 Google 6
6793 2018-04-14 20:23:00.315 Google 7
6794 2018-04-15 08:23:44.873 Google 8
6795 2018-04-15 08:24:07.257 Google 8
6796 2018-04-16 16:42:35.538 Google 9
6797 2018-04-16 16:42:48.351 Google 9
6798 2018-04-17 08:10:54.734 Google 10
6799 2018-04-17 08:13:28.855 Google 10
6800 2018-04-17 08:16:49.408 Google 10
6801 2018-04-17 08:18:55.049 Google 10
6802 2018-04-17 08:21:04.201 Google 10
6803 2018-04-17 08:26:14.254 Google 11
如果您还拥有UserID
,则可以实现逻辑,当时间大于5分钟或UserID
发生变化时,增加ID。这是通过以下方式实现的:
import pandas as pd
data = '''\
1,2018-04-08T09:48:17.573,YouTube
1,2018-04-08T09:47:57.849,Chrome
1,2018-04-08T09:48:28.538,Instagram
1,2018-04-08T09:48:37.381,Maps
2,2018-04-08T09:48:46.680,Netflix
2,2018-04-08T09:48:56.672,Google Play Store
1,2018-04-08T09:56:58.880,Google
1,2018-04-08T09:57:25.461,DB Navigator
1,2018-04-08T11:28:38.762,Google
1,2018-04-08T12:58:31.455,Google
1,2018-04-08T14:31:18.131,Google
1,2018-04-08T14:31:29.209,Google
1,2018-04-08T14:58:42.875,Google
1,2018-04-08T18:18:04.757,Chrome
1,2018-04-08T21:08:41.368,Google
1,2018-04-11T10:53:10.744,Google
1,2018-04-14T19:54:37.441,Google
1,2018-04-14T19:54:59.833,Google
1,2018-04-14T19:55:10.844,YouTube
1,2018-04-14T19:55:34.486,Google
1,2018-04-14T20:23:00.315,Google
2,2018-04-15T08:23:44.873,Google
2,2018-04-15T08:24:07.257,Google'''
df = pd.read_csv(pd.compat.StringIO(data), names=['userID','timestamp','App'],
parse_dates=[1])
df.sort_values(by=['userID','timestamp'], inplace=True)
cond1 = df.timestamp-df.timestamp.shift(1) > pd.Timedelta(5, 'm')
cond2 = df.userID != df.userID.shift(1)
df['SessionID'] = (cond1|cond2).cumsum()
返回:
userID timestamp App SessionID
1 1 2018-04-08 09:47:57.849 Chrome 1
0 1 2018-04-08 09:48:17.573 YouTube 1
2 1 2018-04-08 09:48:28.538 Instagram 1
3 1 2018-04-08 09:48:37.381 Maps 1
6 1 2018-04-08 09:56:58.880 Google 2
7 1 2018-04-08 09:57:25.461 DB Navigator 2
8 1 2018-04-08 11:28:38.762 Google 3
9 1 2018-04-08 12:58:31.455 Google 4
10 1 2018-04-08 14:31:18.131 Google 5
11 1 2018-04-08 14:31:29.209 Google 5
12 1 2018-04-08 14:58:42.875 Google 6
13 1 2018-04-08 18:18:04.757 Chrome 7
14 1 2018-04-08 21:08:41.368 Google 8
15 1 2018-04-11 10:53:10.744 Google 9
16 1 2018-04-14 19:54:37.441 Google 10
17 1 2018-04-14 19:54:59.833 Google 10
18 1 2018-04-14 19:55:10.844 YouTube 10
19 1 2018-04-14 19:55:34.486 Google 10
20 1 2018-04-14 20:23:00.315 Google 11
4 2 2018-04-08 09:48:46.680 Netflix 12
5 2 2018-04-08 09:48:56.672 Google Play Store 12
21 2 2018-04-15 08:23:44.873 Google 13
22 2 2018-04-15 08:24:07.257 Google 13
可能还有比这更有效的方法,但您可以得到如下值: (在您拥有SessionID之后,即) d 您可以通过以下方式获得的金额:
df.groupby('SessionID')['App'].count().sum() # 23
@AntonvBR在这里,以防你没发现。谢谢。好的,现在我明白问题了。但我也能看到有人贴出答案!它看起来是正确的,我投了更高的票。谢谢。如果数据集也有一个userid列,您将如何处理它?现在,我正在按userid和timestamp对列进行排序。但是,一个用户的最新一行与下一个用户的最早一行在同一个会话中被考虑。谢谢@ALollz。我试过了,但会话ID似乎变得依赖于用户(每个用户从1开始)。事实上,我会在一分钟内找到更好的解决方案。让我查一下it@AntonvBR@Moh抱歉,我以为有错误,因为事情不匹配,然后意识到我刚刚更改了一个日期。有了正确的首字母
df
@ALollz,现在一切都好了。我更新了你的答案,使之更具可读性。干得好@卫生部你问“我想知道数据集中有多少个移动会话。另外,我想知道每个会话中启动了哪些应用程序。”或者你想要另一种格式吗?啊,是的,我现在知道了。谢谢
{1: {'Chrome': 1, 'Instagram': 1, 'Maps': 1, 'Netflix': 1, 'YouTube': 1},
2: {'Google': 1, 'Google Play Store': 1},
3: {'DB Navigator': 1},
4: {'Google': 1},
5: {'Google': 2},
6: {'Google': 1},
7: {'Google': 1},
8: {'Chrome': 1},
9: {'Google': 1},
10: {'Google': 3, 'YouTube': 1},
11: {'Google': 1},
12: {'Google': 3}}
df.groupby('SessionID')['App'].count().sum() # 23