DataFrame 新列按时间差分割会话 - pandas

我有以下排序的数据框:


import pandas as pd


hits = {'id': ['A','A','A','A','B','B','C','C'],

        'datetime': ['2010-01-02 03:00:00','2010-01-02 03:05:10','2010-01-02 03:51:35','2010-01-02 04:40:20',

                    '2010-01-02 03:29:10','2010-01-02 03:29:15','2010-01-02 03:45:20','2010-01-02 06:10:05'],

        'value': [1,2,2,1,1,3,2,4]

       }


df = pd.DataFrame(hits, columns = ['id', 'datetime','value'])


df['datetime'] =  pd.to_datetime(df['datetime'], format='%Y-%m-%d %H:%M:%S')


print (df)



  id            datetime  value

0  A 2010-01-02 03:00:00      1

1  A 2010-01-02 03:05:10      2

2  A 2010-01-02 03:51:35      2

3  A 2010-01-02 04:40:20      1

4  B 2010-01-02 03:29:10      1

5  B 2010-01-02 03:29:15      3

6  C 2010-01-02 03:45:20      2

7  C 2010-01-02 06:10:05      4

该列id允许我区分独特的用户,但我想向前迈出一步,能够按会话对点击进行分组。一次会话定义为不活动时间不超过 30 分钟的所有用户活动。


在我的 DataFrame 中,所需的输出应该是:


  id            datetime  value  session

0  A 2010-01-02 03:00:00      1        1

1  A 2010-01-02 03:05:10      2        1

2  A 2010-01-02 03:51:35      2        2

3  A 2010-01-02 04:40:20      1        3

4  B 2010-01-02 03:29:10      1        1

5  B 2010-01-02 03:29:15      3        1

6  C 2010-01-02 03:45:20      2        1

7  C 2010-01-02 06:10:05      4        2

在中SQL,我将首先使用lag来计算点击次数之间的差异partition by id order by datetime asc,然后在新的查询中,我sum(case when diff > 30min then 1 else 0 end)也将按 id 进行分区。


Pandas 有类似的东西吗?


aluckdog
浏览 43回答 2
2回答

牧羊人nacy

这是一种常用的技术,用于cumsum与diff阈值进行比较来识别由阈值分隔的块。就像是:series.diff().gt('30Min').cumsum()由于您想通过 id 查找块,因此只需将其包装在groupby():df['session'] = (df.groupby('id')['datetime']                   .transform(lambda x: x.diff().gt('30Min').cumsum())                )输出:  id            datetime  value  session0  A 2010-01-02 03:00:00      1        01  A 2010-01-02 03:05:10      2        02  A 2010-01-02 03:51:35      2        13  A 2010-01-02 04:40:20      1        24  B 2010-01-02 03:29:10      1        05  B 2010-01-02 03:29:15      3        06  C 2010-01-02 03:45:20      2        07  C 2010-01-02 06:10:05      4        1

慕村225694

你可以做双重.groupby:如果时间超过 30 分钟,您可以创建一个使用on并返回或 的boolean series调用,用于每个组中的每一行。s.groupbyidTrueFalseid然后,您可以再次对步骤 1 中创建的进行 groupby并返回累积计数.cumsum并加 1,以便从 1 而不是 0 开始计数df['session'] = (df.assign(session=(df.groupby('id')['datetime'].diff() > '00:30:00')                                      .astype(int))                   .groupby('id')['session'].cumsum() + 1)Out[1]:   id            datetime  value  session0  A 2010-01-02 03:00:00      1        11  A 2010-01-02 03:05:10      2        12  A 2010-01-02 03:51:35      2        23  A 2010-01-02 04:40:20      1        34  B 2010-01-02 03:29:10      1        15  B 2010-01-02 03:29:15      3        16  C 2010-01-02 03:45:20      2        17  C 2010-01-02 06:10:05      4        2
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python