如何使用pandas按天分组对比行数据 计算跨天模式的持续时长
pandas实现跨天模式时长拆分计算
实现逻辑
基于你给出的C语言逻辑,用pandas实现时可以通过行处理+展开的方式完成跨天拆分,避免手动循环插入行的繁琐操作,具体实现代码如下:
import pandas as pd from datetime import timedelta # 构造示例数据,你可以替换为自己的数据源 data = { 'TS': ['2021/9/15 10:00:00', '2021/9/15 16:00:00', '2021/9/16 05:00:00', '2021/9/16 10:00:00', '2021/9/16 12:00:00'], 'mode': ['A', 'B', 'A', 'C', 'B'] } df = pd.DataFrame(data) # 1. 转换时间列为datetime格式,保证时间顺序正确 df['TS'] = pd.to_datetime(df['TS']) # 提前读取每行的下一个时间戳,用于计算时长 df['next_ts'] = df['TS'].shift(-1) # 2. 定义跨天拆分逻辑 def split_cross_day(row): curr_ts = row['TS'] mode = row['mode'] next_ts = row['next_ts'] # 最后一行没有下一个时间,时长返回空 if pd.isna(next_ts): return [(curr_ts, mode, pd.NA)] # 计算当前日期的次日0点作为当天结束时间 curr_date_end = (curr_ts + timedelta(days=1)).replace(hour=0, minute=0, second=0, microsecond=0) res = [] if next_ts < curr_date_end: # 同天数据直接计算时长 duration = (next_ts - curr_ts).total_seconds() / 3600 res.append((curr_ts, mode, duration)) else: # 跨天数据拆分为两条 # 第一条为当天剩余时长 duration1 = (curr_date_end - curr_ts).total_seconds() / 3600 res.append((curr_ts, mode, duration1)) # 第二条为次日0点到下一个时间点的时长 duration2 = (next_ts - curr_date_end).total_seconds() / 3600 res.append((curr_date_end, mode, duration2)) return res # 3. 应用逻辑并展开生成最终结果 processed_data = df.apply(split_cross_day, axis=1).explode().tolist() result = pd.DataFrame(processed_data, columns=['TS', 'mode', 'mode duration time(hour)']) # 输出结果 print(result)
输出结果
TS mode mode duration time(hour) 0 2021-09-15 10:00:00 A 6.0 1 2021-09-15 16:00:00 B 8.0 2 2021-09-16 00:00:00 B 5.0 3 2021-09-16 05:00:00 A 5.0 4 2021-09-16 10:00:00 C 2.0 5 2021-09-16 12:00:00 B <NA>
内容的提问来源于stack exchange,提问作者Ryou
相关产品推荐
相关产品推荐

