如何拆分Pandas DataFrame中跨日期的停机时间戳记录
拆分跨日期的压缩机停机记录
问题说明
你需要将DataFrame中跨日期的停机时间段拆分为按日分段的记录,当前尝试的代码存在列名不匹配(数据列是start/end,函数里写了Start time)、未转换时间类型等问题,导致无法正常运行。
解决方案
以下是可直接运行的完整代码:
import pandas as pd # 原数据集 df = pd.DataFrame({ 'Compressor #': [0, 0, 0, 0], 'start': ['2023-04-13 14:35:00', '2023-04-13 23:40:00', '2023-04-14 07:50:00', '2023-04-19 07:32:39'], 'end': ['2023-04-13 16:05:00', '2023-04-14 02:00:00', '2023-04-14 10:45:00', '2023-04-19 08:41:08'] }) # 第一步:转换时间列为datetime类型(必须步骤) df['start'] = pd.to_datetime(df['start']) df['end'] = pd.to_datetime(df['end']) # 定义拆分跨天记录的函数 def split_daily_intervals(row): start = row['start'] end = row['end'] # 同天时间段直接返回原记录 if start.date() == end.date(): return [(start, end)] # 跨天情况拆分时间段 intervals = [] # 第一天的结束时间:当天23:59:59.999 first_day_end = start.replace(hour=23, minute=59, second=59, microsecond=999999) intervals.append((start, first_day_end)) # 处理中间的完整天数(如果存在) current_date = start.date() + pd.Timedelta(days=1) while current_date < end.date(): day_start = pd.Timestamp(current_date) day_end = day_start.replace(hour=23, minute=59, second=59, microsecond=999999) intervals.append((day_start, day_end)) current_date += pd.Timedelta(days=1) # 最后一天的开始时间:当天00:00:00 last_day_start = end.replace(hour=0, minute=0, second=0, microsecond=0) intervals.append((last_day_start, end)) return intervals # 应用函数并展开结果 df['intervals'] = df.apply(split_daily_intervals, axis=1) df_expanded = df.explode('intervals') # 拆分元组列为新的start/end列 df_expanded[['start', 'end']] = pd.DataFrame(df_expanded['intervals'].tolist(), index=df_expanded.index) # 移除临时列得到最终结果 final_df = df_expanded.drop(columns=['intervals']) print(final_df)
输出结果
Compressor # start end 0 0 2023-04-13 14:35:00 2023-04-13 16:05:00 1 0 2023-04-13 23:40:00 2023-04-13 23:59:59.999999 1 0 2023-04-14 00:00:00 2023-04-14 02:00:00 2 0 2023-04-14 07:50:00 2023-04-14 10:45:00 3 0 2023-04-19 07:32:39 2023-04-19 08:41:08
代码说明
- 时间类型转换:确保
start和end为datetime对象,才能进行日期比较与运算 - 拆分逻辑:
- 同天时间段直接保留原记录
- 跨天记录拆分为:第一天结束(当日午夜前)、中间完整天数(全天时间段)、最后一天开始(当日午夜后)
- 结果展开:通过
explode将列表形式的时间段拆分为多行,再拆分元组为独立的时间列
内容的提问来源于stack exchange,提问作者Gtoth
相关产品推荐
相关产品推荐

