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

基于小时级起止时间的游戏时长占比统计Python需求

游戏会话时段时长统计实现思路

我跟踪了一整年的游戏会话数据,想借此学习Python并提取关注的统计数据。需要统计一天中0-23点每个时段的总游玩时长、日均游玩时长,还要计算每个小时的游玩时长占比(不是只标记是否游玩)。网上大多是按天/月计数事件的方案,没找到涉及时长占比计算的,求实现思路参考。

示例输入表

session_idgame_idstart_datetimeend_datetime
001742023-02-22 13:15:002023-02-22 15:30:00
0021272023-02-23 13:30:002023-02-23 13:45:00
003742023-02-24 14:40:002023-02-24 15:00:00

预期输出表

hour_of_daysum_hours_playedavg_hours_played_per_daycalculation
131.000.33(0.75 + 0.25) / 3 days
141.330.44(1.00 + 0.33) / 3 days
150.500.17(0.50) / 3 days

核心实现思路

1. 数据预处理

  • 将start_datetime和end_datetime转换为Python可识别的datetime对象,方便后续时间计算。用Pandas可直接调用pd.to_datetime(),原生Python用datetime.strptime()。
  • 无需提前计算会话总时长,重点是处理跨小时的分段拆分。

2. 拆分跨小时会话(关键步骤)

单个游戏会话可能覆盖多个小时(比如示例中session001从13:15到15:30,覆盖13、14、15三个小时),必须把每个会话拆分成对应小时的分段时长:

  • 对每个会话,先确定它覆盖的所有小时区间(从起始时间的小时到结束时间的小时)。
  • 针对每个覆盖的小时:
    • 起始小时:计算从会话开始时间到该小时结束的时长(比如13:15到14:00,时长为0.75小时)。
    • 结束小时:计算从该小时开始到会话结束时间的时长(比如15:00到15:30,时长为0.5小时)。
    • 中间小时:时长直接按1小时计算。

3. 按小时聚合统计

  • 将拆分后的所有小时段数据,按hour_of_day分组,求和得到sum_hours_played。
  • 计算跟踪周期的总天数(从第一天到最后一天的天数,包含首尾)。
  • 每个小时的avg_hours_played_per_day = 该小时总时长 / 总天数。
  • 时长占比:用每个小时的sum_hours_played除以所有小时的总游玩时长之和,即可得到该时段的占比。

4. Python代码实现示例(基于Pandas)

import pandas as pd
from datetime import datetime, timedelta

# 加载示例数据(实际使用时替换为你的数据源)
data = {
    'session_id': ['001', '002', '003'],
    'game_id': [74, 127, 74],
    'start_datetime': ['2023-02-22 13:15:00', '2023-02-23 13:30:00', '2023-02-24 14:40:00'],
    'end_datetime': ['2023-02-22 15:30:00', '2023-02-23 13:45:00', '2023-02-24 15:00:00']
}
df = pd.DataFrame(data)

# 转换时间列为datetime类型
df['start_datetime'] = pd.to_datetime(df['start_datetime'])
df['end_datetime'] = pd.to_datetime(df['end_datetime'])

# 定义函数:将单个会话拆分为各小时的时长片段
def split_to_hour_segments(row):
    start = row['start_datetime']
    end = row['end_datetime']
    segments = []
    current_hour_start = start.replace(minute=0, second=0)
    
    while current_hour_start < end:
        current_hour_end = current_hour_start + timedelta(hours=1)
        # 计算当前片段的实际起止时间
        segment_start = max(start, current_hour_start)
        segment_end = min(end, current_hour_end)
        # 转换为小时数
        duration_hours = (segment_end - segment_start).total_seconds() / 3600
        
        segments.append({
            'hour_of_day': current_hour_start.hour,
            'duration': duration_hours,
            'date': start.date()
        })
        current_hour_start = current_hour_end
    
    return segments

# 应用函数并展开所有小时片段
hour_segments = df.apply(split_to_hour_segments, axis=1).explode()
hour_segments = pd.DataFrame(hour_segments.tolist())

# 计算跟踪周期的总天数
total_days = (hour_segments['date'].max() - hour_segments['date'].min()).days + 1

# 按小时聚合统计
result = hour_segments.groupby('hour_of_day').agg(
    sum_hours_played=('duration', 'sum'),
    daily_durations=('duration', list)  # 保留每日时长用于生成计算说明
).reset_index()

# 计算日均时长
result['avg_hours_played_per_day'] = result['sum_hours_played'] / total_days

# 生成计算说明文本
result['calculation'] = result.apply(
    lambda x: f"({'+'.join([f'{d:.2f}' for d in x['daily_durations']])}) / {total_days} days",
    axis=1
)

# 格式化数值保留两位小数
result['sum_hours_played'] = result['sum_hours_played'].round(2)
result['avg_hours_played_per_day'] = result['avg_hours_played_per_day'].round(2)

# 输出结果
print(result[['hour_of_day', 'sum_hours_played', 'avg_hours_played_per_day', 'calculation']])

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 11:17:50