大家好,我是Brook。
最近在处理数据的时候遇到一个需求,核心就是求取最大连续行为天数。
这里从数据库中导出的监测设备数据离线预警日志,需求是找出各监测对象设备掉线最长持续多久并确定其离线时长。
图1:案例数据
以上某监测对象数据显示:最长离线天数从5月7日-5月10日持续4天。
程序每天定时检测一次数据在线情况,很明显只有数据掉线才会向数据库中插入日志,时间并不连续,因此,本文分享一种思路来统计时间序列连续时间段和天数。
案例数据较简单,大家可以自行虚拟构造演示数据集,定义的字段相同即可。
整体思路如下:
具体代码如下:
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)
以上为本次分享全部内容,类似场景可触类旁通如:计算用户连续打卡天数、计算用户连续登录天数等!
本文分享自 Python数据分析实例 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体同步曝光计划 ,欢迎热爱写作的你一起参与!