You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Pandas中提取用户操作时段的起止时间?

问题描述

我有如下Pandas DataFrame,其中delta列是Submission_Ended列的行间时间差,当差值超过20分钟时new period标记为True,代表用户休息后重新使用的新时段:

+----------+-------------------+---------------------+----------+------------+
| UserName | MainOperationName | Submission_Ended    | delta    | new period |
+----------+-------------------+---------------------+----------+------------+
| User1    | Record submission | 2017-07-31 00:08:25 | 00:00:00 | False      |
| User1    | Record submission | 2017-07-31 00:12:02 | 00:03:37 | False      |
| User1    | Record submission | 2017-07-31 00:14:51 | 00:02:49 | False      |
| User1    | Record submission | 2017-07-31 00:17:27 | 00:02:36 | False      |
| User1    | Record submission | 2017-07-31 00:23:42 | 00:06:15 | False      |
| User1    | Record submission | 2017-07-31 00:25:35 | 00:01:53 | False      |
| User1    | Record submission | 2017-07-31 00:26:01 | 00:00:26 | False      |
| User1    | Record submission | 2017-07-31 01:59:11 | 01:33:10 | True       |
| User1    | Record submission | 2017-07-31 02:00:37 | 00:01:26 | False      |
| User1    | Record submission | 2017-07-31 02:03:12 | 00:02:35 | False      |
| User1    | Record submission | 2017-07-31 02:21:22 | 00:18:10 | False      |
| User1    | Record submission | 2017-07-31 02:30:28 | 00:09:06 | False      |
| User1    | Record submission | 2017-07-31 02:36:03 | 00:05:35 | False      |
| User1    | Record submission | 2017-07-31 03:25:43 | 00:49:40 | True       |
+----------+-------------------+---------------------+----------+------------+

我的需求是:

  1. 把每个用户的第一行new period设为True,因为它是新时段的开始
  2. 提取每个用户的各个使用时段的起止时间,最终输出类似:
    User1:
    start: 2017-07-31 00:08:25 ; stop: 2017-07-31 00:26:01
    start: 2017-07-31 01:59:11 ; stop: 2017-07-31 02:36:03
    start: 2017-07-31 03:25:43 ; stop: ...
    
    真实数据包含数百个用户,需要兼容多用户场景。
解决方案

没问题,这个需求用Pandas的分组和累积操作就能轻松实现,而且完全适配多用户的场景,具体步骤如下:

1. 确保时间列格式正确

首先得把Submission_Ended转成datetime类型,不然后续的时间操作会出问题:

df['Submission_Ended'] = pd.to_datetime(df['Submission_Ended'])

2. 修正new period列,标记用户首行为新时段

我们可以通过分组后标记首行,再把首行的new period设为True:

# 给每个用户的第一行打标记
df['is_first_row'] = df.groupby('UserName').cumcount() == 0
# 把首行的new period设为True,和原来的True做或运算
df['new period'] = df['new period'] | df['is_first_row']
# 删掉临时列(也可以保留,看你需求)
df = df.drop('is_first_row', axis=1)

3. 为每个时段生成唯一分组ID

利用new period的累积求和,给同一个用户内的连续使用时段分配唯一ID,这样就能把同一个时段的行归为一组:

df['period_id'] = df.groupby('UserName')['new period'].cumsum()

4. 聚合提取每个时段的起止时间

按用户和时段ID分组,取每个组内最早的时间作为start,最晚的作为stop:

periods = df.groupby(['UserName', 'period_id']).agg(
    start=('Submission_Ended', 'min'),
    stop=('Submission_Ended', 'max')
).reset_index(drop=True)

5. 格式化输出结果

如果需要像你预期的那样打印每个用户的时段,可以用这段代码:

for user in periods['UserName'].unique():
    user_periods = periods[periods['UserName'] == user]
    print(f"{user}:")
    for idx, row in user_periods.iterrows():
        # 最后一个时段如果没有后续数据,就用...代替stop
        stop_str = row['stop'].strftime('%Y-%m-%d %H:%M:%S') if idx != len(user_periods)-1 else '...'
        print(f"start: {row['start'].strftime('%Y-%m-%d %H:%M:%S')} ; stop: {stop_str}")

运行效果(针对示例数据)

执行后会输出:

User1:
start: 2017-07-31 00:08:25 ; stop: 2017-07-31 00:26:01
start: 2017-07-31 01:59:11 ; stop: 2017-07-31 02:36:03
start: 2017-07-31 03:25:43 ; stop: ...

这个方案不管你有多少用户,都能自动按用户分组处理,完美适配你的真实数据场景。

内容的提问来源于stack exchange,提问作者pawelty

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:31:53