首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >python pandas -处理嵌套groupby的最佳方式

python pandas -处理嵌套groupby的最佳方式
EN

Stack Overflow用户
提问于 2021-10-24 17:12:00
回答 2查看 67关注 0票数 0

我目前正在尝试使用python和pandas库来处理一些日志文件。日志包含有关发送到服务器的请求的简单信息,我希望从中提取有关会话的信息。这里的会话定义为同一用户在特定时间段内提出的一组请求(例如,30分钟,从第一次请求的时间到最后一次请求的时间,此时间段之后的请求应被视为新会话的一部分)

要做到这一点,目前我正在执行嵌套分组:首先,我使用groupby获取每个用户的请求,然后按30分钟间隔对每个用户的请求进行分组,最后迭代这些间隔并选择那些实际包含数据的请求:

代码语言:javascript
运行
复制
    # example log entry:
    # id,host,time,method,url,response,bytes
    # 303372,XXX.XXX.XXX.XXX,1995-07-11 12:17:09,GET,/htbin/wais.com?IMAX,200,6923

       by_host = logs.groupby('host', sort=False)
         for host, frame in by_host:
           by_frame = frame.groupby(pd.Grouper(key='time', freq='30min', origin='start'))
           for date, logs in by_frame:
             if not logs.empty and logs.shape[0] > 1:
                session_calculations()

这当然是相当低效的,并且使计算花费了相当多的时间。有什么方法可以优化这个过程吗?我没能想出任何成功的东西。

编辑:

代码语言:javascript
运行
复制
                  host                time method                                           url  response  bytes
0          ***.novo.dk 1995-07-11 12:17:09    GET                                     /ksc.html       200   7067
1          ***.novo.dk 1995-07-11 12:17:48    GET               /shuttle/missions/missions.html       200   8678
2          ***.novo.dk 1995-07-11 12:23:10    GET     /shuttle/resources/orbiters/columbia.html       200   6922
3          ***.novo.dk 1995-08-09 12:48:48    GET  /shuttle/missions/sts-69/mission-sts-69.html       200  11264
4          ***.novo.dk 1995-08-09 12:49:48    GET               /shuttle/countdown/liftoff.html       200   4665

预期结果是从请求中提取的会话列表:

代码语言:javascript
运行
复制
   host session_time
0  ***.novo.dk 00:06:01 
1  ***.novo.dk 00:01:00

请注意,这里的session_time是将来自输入的第一个请求和最后一个请求分组到30分钟的时间窗口后,它们之间的时间差。

EN

回答 2

Stack Overflow用户

发布于 2021-10-24 17:38:14

要为每个用户定义本地时间窗口,即将起始点视为每个用户第一次请求的时间,您可以首先按'host‘进行分组。然后使用GroupBy.apply对每个用户的DataFrame应用一个函数,该函数处理时间分组并计算用户会话的持续时间。

代码语言:javascript
运行
复制
def session_duration_by_host(by_host):
    time_grouper = pd.Grouper(key='time', freq='30min', origin='start')
    duration = lambda time: time.max() - time.min()
    return ( 
        by_host.groupby(time_grouper)
               .agg(session_time = ('time', duration))
    )

res = (
    logs.groupby("host")
        .apply(session_duration_by_host)
        .reset_index()
        .drop(columns="time")
)
票数 0
EN

Stack Overflow用户

发布于 2021-10-24 17:55:36

代码语言:javascript
运行
复制
# You have to write idiomatic Pandas code, so rather then processing something -> saving into variable -> using that variable (only once) to something -> ....  you have to chain your process. Also pandas `apply` is much faster than normal `for` in most situations.

logs.groupby('host', sort=False).apply(
    lambda by_frame:by_frame.groupby(
        pd.Grouper(key='time', freq='30min', origin='start')
    ).apply(lambda logs: session_calculations() if (not logs.empty) and (logs.shape[0] > 1) else None)
)
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69699054

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档