【问题标题】:Creating interaction sessions based on timestamps in pandas根据 pandas 中的时间戳创建交互会话
【发布时间】:2018-10-22 23:38:53
【问题描述】:

我正在尝试定义在不同的移动使用会话中使用了哪些应用。基本上,一个会话是由一个 单个用户在很短的时间范围内(又名会话增量)。换句话说,如果在前一次的 5 分钟内没有发生交互 交互时,用户的会话被视为关闭。下一个 交互被视为一个单独的会话。我想知道数据集中有多少移动会话。另外,我想知道每个会话中启动了哪些应用程序。 我的数据框中的所有行都带有时间戳。 这是数据集中的一个示例:

        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

【问题讨论】:

  • @AntonvBR 以防万一您还没有发现它。谢谢。
  • 好的,现在我明白了问题所在。但我也可以看到有人发布了答案!它看起来正确,我赞成。

标签: python pandas time-series


【解决方案1】:

我想你想要.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

【讨论】:

  • 谢谢。如果数据集也有一个 userid 列,你将如何处理它?现在,我正在按用户 ID 和时间戳对列进行排序。但是,用户的最新行被视为与下一个用户的最早行在同一会话中。
  • 谢谢@ALollz。我试过了,但似乎会话 ID 变得依赖于用户(每个用户从 1 开始)。
  • 其实我马上就有更好的解决方案。让我检查一下
  • @AntonvBR @Moh 对不起,我以为有错误,因为事情不匹配,然后意识到我刚刚更改了其中一个日期。正确的初始 df 现在一切都很好
  • @ALollz 我更新了您的答案,使其更具可读性。干得好!
【解决方案2】:

可能有比这更有效的方法,但您可以像这样获得价值计数:

(在你拥有 SessionID 之后)

from collections import defaultdict

d = defaultdict(dict)
for k,v in df.groupby('SessionID')['App'].value_counts().items():
    d[k[0]].update({k[1]:v})

d

{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

【讨论】:

  • @Moh 你问“我想知道数据集中有多少个移动会话。另外,我想知道每个会话中启动了哪些应用程序。”还是您想要其他格式?
  • 啊,是的,我现在明白了。谢谢。
猜你喜欢
  • 2022-07-11
  • 2022-12-18
  • 2022-07-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-17
  • 2023-04-09
相关资源
最近更新 更多