前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python判断连续时间序列范围并分组应用

Python判断连续时间序列范围并分组应用

作者头像
用户8949263
发布2022-04-08 12:35:12
1.9K0
发布2022-04-08 12:35:12
举报
文章被收录于专栏:Python数据分析实例

大家好,我是Brook。

最近在处理数据的时候遇到一个需求,核心就是求取最大连续行为天数。

这里从数据库中导出的监测设备数据离线预警日志,需求是找出各监测对象设备掉线最长持续多久并确定其离线时长。

图1:案例数据

以上某监测对象数据显示:最长离线天数从5月7日-5月10日持续4天。

程序每天定时检测一次数据在线情况,很明显只有数据掉线才会向数据库中插入日志,时间并不连续,因此,本文分享一种思路来统计时间序列连续时间段和天数。

案例数据较简单,大家可以自行虚拟构造演示数据集,定义的字段相同即可。

整体思路如下:

  • 构造日期天数辅助列(定义日期转天数函数)
  • 然后用辅助列生成列表作为输入,构造时间序列处理函数生成可分段时间范围和天数
  • 如果掉线天数与最大掉线天数相同,则这几天是最长连续离线日期范围(当然还可以求最近多少天内掉线情况、连续掉线最长时间段等,根据需要增加过滤条件)

具体代码如下:

代码语言:javascript
复制
import pandas as pd
from itertools import groupby

#日期-天数转换函数
def which_day(x):
    year=x.year
    month=x.month
    day=x.day
    list=[31,28,31,30,31,30,31,31,30,31,30,31]
    whichday=0
    if (year%4)==0 and (year%100)!=0 or (year%400)==0:
        list[1]=29
    for i in range(1,month):
        if month == 1:
            print(day)
        whichday=whichday+list[i-1]
    whichday=whichday+day
    return whichday

#连续掉线时间范围及天数处理函数
def data_preprocess_dactory(lst,BUILD_ID):
    result1 = []
    result2 = []
    for k, g in groupby(enumerate(lst), lambda x: x[1] - x[0]):
        l1 = [k_v.get(j).strftime('%Y-%m-%d') for i, j in g]  # 连续时间的列表
        if len(l1) > 1:
            scop = str(min(l1)) + '-' + str(max(l1))  # 连续时间范围用"-"连接
            result1.append(scop)
            result2.append(len(l1))  #连续天数
        else:
            scop = l1[0]
            result1.append(scop)
            result2.append(len(l1))   #连续天数
    df = pd.DataFrame({'时间': result1, '连续掉线天数': result2})

    return df.reindex(columns=["建筑编号", "时间", "连续掉线天数"], fill_value="{0}".format(BUILD_ID))


# 数据源
df = pd.read_excel(r".\test.xlsx")
df1=pd.DataFrame(df[["BUILD_ID","BUILD_NAME","OFF_TIME"]])
id_name =df1.set_index("BUILD_ID")["BUILD_NAME"].to_dict()  #ID-名称映射字典
Build_list=df1.BUILD_ID.unique().tolist()

# 构建空表,存储处理的对象
df_empty = pd.DataFrame(columns=["建筑编号", "建筑名称", "时间", "连续掉线天数"])
data_list = [] 
for k in range(len(Build_list)):
    df2=df1[df1.BUILD_ID=="{0}".format(Build_list[k])].copy()

    df2["OFF_TIME"]=pd.to_datetime(df2['OFF_TIME'])
    df2["辅助列-天数"]=df2["OFF_TIME"].map(lambda x:which_day(x))

    lst = df2["辅助列-天数"].tolist()   # 连续数字
    # lst1=df2["OFF_TIME"].dt.strftime('%Y-%m-%d').tolist()
    k_v = df2.set_index("辅助列-天数")["OFF_TIME"].to_dict()  #辅助列-天数映射字典

    df3=data_preprocess_dactory(lst,Build_list[k])

    df3.insert(1,'建筑名称',df3["建筑编号"].map(lambda x:id_name.get(x)))  # 指定第2列插入建筑名称
    # df3["建筑名称"]=df3["建筑编号"].map(lambda x:id_name.get(x))

    data_list.append(df3)

res = pd.concat(data_list, axis=0, ignore_index=True,sort=False)
print(res)

res["max_连续掉线天数"]=res.groupby("建筑编号")["连续掉线天数"].transform('max')
res1=res[res.连续掉线天数==res.max_连续掉线天数]

print(res1)

以上为本次分享全部内容,类似场景可触类旁通如:计算用户连续打卡天数计算用户连续登录天数等!

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-05-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Python数据分析实例 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档