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

如何基于位置与时间数据计算设备不同场景的时长占比

问题描述

我拥有两个DataFrame:

import pandas as pd

loc_hour = pd.DataFrame({'id': ['a', 'b', 'c',"d"], 'geohash': ["sybewp", "sws101", "sxk9db","sxr4xt"],"log_date":[20210615,20211219,20210108,20210507],"hour":[12,4,5,19]})

loc_grid = pd.DataFrame({'id': ['a', 'b', 'c',"d"], 'geohash': ["sybewp", "sws101", "sxk9db","sxr4xt"], "gridtype":["Home","Other","Work","Home"]})

这两张表包含数千个不同设备的数据。其中loc_hour表存储了一整年中每小时的设备位置信息;loc_grid表记录了设备所在位置的属性(Home代表设备处于家中,Work代表设备处于工作场所)。

我需要计算设备在家庭、工作、其他场景的时长,分别占短期(1个月)和长期(3个月)总时长的百分比,期望输出如下格式的统计表格:

短期(最近1个月)统计

idhome_percentwork_percentother_percenttotal_day_counttotal_hour_countperiod
a40402055last 1 month
b503020108last 1 month
c70201097last 1 month
.....................

长期(最近3个月)统计

idhome_percentwork_percentother_percenttotal_day_counttotal_hour_countperiod
a40402055last 3 month
b503020108last 3 month
c70201097last 3 month
.....................
解决方案

以下是实现需求的Python代码:

import pandas as pd
from datetime import datetime, timedelta

# 1. 转换日期格式为datetime类型
loc_hour['log_date'] = pd.to_datetime(loc_hour['log_date'], format='%Y%m%d')

# 2. 关联两张表,为每条位置记录添加上场景属性
merged_data = pd.merge(loc_hour, loc_grid, on=['id', 'geohash'], how='left')

# 3. 定义统计的时间周期:以数据中最新日期为基准
latest_date = merged_data['log_date'].max()
time_periods = [
    ('last 1 month', latest_date - timedelta(days=30)),
    ('last 3 month', latest_date - timedelta(days=90))
]

result_collection = []

for period_name, cutoff_date in time_periods:
    # 筛选当前周期内的数据
    period_data = merged_data[merged_data['log_date'] >= cutoff_date]
    
    # 按设备ID分组计算核心指标
    group_stats = period_data.groupby('id').agg(
        total_hour_count=('hour', 'count'),
        total_day_count=('log_date', lambda x: x.nunique()),
        home_hours=('gridtype', lambda x: (x == 'Home').sum()),
        work_hours=('gridtype', lambda x: (x == 'Work').sum()),
        other_hours=('gridtype', lambda x: (x == 'Other').sum())
    ).reset_index()
    
    # 计算各场景时长占比,避免除数为0的情况
    group_stats['home_percent'] = group_stats.apply(
        lambda row: round(row['home_hours'] / row['total_hour_count'] * 100, 2) if row['total_hour_count'] > 0 else 0,
        axis=1
    )
    group_stats['work_percent'] = group_stats.apply(
        lambda row: round(row['work_hours'] / row['total_hour_count'] * 100, 2) if row['total_hour_count'] > 0 else 0,
        axis=1
    )
    group_stats['other_percent'] = group_stats.apply(
        lambda row: round(row['other_hours'] / row['total_hour_count'] * 100, 2) if row['total_hour_count'] > 0 else 0,
        axis=1
    )
    
    # 添加周期标识并整理列顺序
    group_stats['period'] = period_name
    formatted_result = group_stats[['id', 'home_percent', 'work_percent', 'other_percent', 'total_day_count', 'total_hour_count', 'period']]
    
    result_collection.append(formatted_result)

# 合并两个周期的统计结果
final_result = pd.concat(result_collection, ignore_index=True)

# 输出最终结果
print(final_result)

代码说明

  • 日期转换:将字符串格式的日期转为datetime类型,支持后续时间范围筛选。
  • 表关联:通过id和geohash两个字段关联两张表,让每条位置记录匹配对应的场景属性。
  • 周期筛选:以数据中的最新日期为基准,分别截取最近1个月和3个月的数据。
  • 分组统计:按设备ID分组,统计总时长、总天数,以及家庭、工作、其他场景的各自时长。
  • 占比计算:计算各场景时长占总时长的百分比,处理总时长为0的异常情况。
  • 结果整合:将两个周期的统计结果合并,输出符合需求的格式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 21:15:37