Pandas DataFrame分组统计时间差 计算组件可用与占用总时长
实现步骤
你之前直接分组求和时间差出错,核心原因是没有先计算每个状态条目的有效持续时长。原始数据里的Timestamp是状态的生效时间,单条数据本身没有时长信息,需要通过相邻的状态时间差计算。
具体实现代码如下:
1. 预处理时间列
首先把字符串格式的时间转换成pandas可运算的datetime类型:
import pandas as pd # 匹配你提供的时间格式:日.月.年-时:分.秒 df["Timestamp"] = pd.to_datetime(df["Timestamp"], format="%d.%m.%Y-%H:%M.%S")
2. 计算单条状态的持续时长
按组件分组后按时间排序,用下一条状态的生效时间减去当前状态的生效时间,得到当前状态的持续时长:
# 按组件+时间升序排序,保证时间线正确 df = df.sort_values(by=["ComponentName", "Timestamp"]).reset_index(drop=True) # 同组件内,下一行时间减当前行时间,得到当前状态的持续时长 df["duration"] = df.groupby("ComponentName")["Timestamp"].shift(-1) - df["Timestamp"] # 可选配置:如果最后一条状态需要统计到指定结束时间,补充这部分代码即可 # end_time = pd.to_datetime('你需要的统计结束时间,格式如2020-10-26 00:00:00') # df['duration'] = df['duration'].fillna(end_time - df['Timestamp'])
3. 按状态分组求和并格式化输出
按组件和状态分组对时长求和,再转换成你需要的可读格式:
# 分组求和后透视成目标表结构 res = df.groupby(["ComponentName", "Utilization"])["duration"].sum().unstack().reset_index() # 重命名列名 res.columns = ["ComponentName", "Total_Available_time", "Total_Inuse_time"] # 格式化timedelta为 天+小时 的可读形式 def format_duration(td): if pd.isna(td): return "0" days = td.days hours = td.seconds // 3600 res_str = [] if days: res_str.append(f"{days} days") if hours: res_str.append(f"{hours} hours") return " ".join(res_str) if res_str else "0" res["Total_Available_time"] = res["Total_Available_time"].apply(format_duration) res["Total_Inuse_time"] = res["Total_Inuse_time"].apply(format_duration)
执行后输出的res就是你要求的结果格式。
内容的提问来源于stack exchange,提问作者Elgun Valiyev
相关产品推荐
相关产品推荐

