基于全年通信中断事件数据集生成1分钟时序状态数据框需求
嘿,这个需求我刚好实操过,用Pandas就能完美解决,给你一步步拆解清楚:
实现思路与代码示例
1. 先搭好基础:生成全年1分钟时间序列
首先得创建目标DataFrame的核心——全年每分钟的时间戳。用pd.date_range就能轻松生成,记得指定年份和频率:
import pandas as pd import numpy as np # 以2023年为例,生成全年每分钟的时间序列 start_date = '2023-01-01 00:00:00' end_date = '2023-12-31 23:59:00' time_df = pd.DataFrame({'timestamp': pd.date_range(start=start_date, end=end_date, freq='T')})
2. 预处理原始中断数据集
先确保你的原始中断数据里的起止时间是datetime类型,不然没法做时间判断。我先模拟一份原始数据给你参考:
# 模拟原始中断记录(实际替换成你的真实数据即可) raw_outages = pd.DataFrame({ 'line_id': ['L001', 'L001', 'L002'], 'outage_start': ['2023-05-10 08:30:00', '2023-09-01 14:00:00', '2023-02-20 10:00:00'], 'outage_end': ['2023-05-10 09:15:00', '2023-09-01 14:45:00', '2023-02-20 10:30:00'] }) # 把起止时间转换为datetime类型,这步很关键! raw_outages['outage_start'] = pd.to_datetime(raw_outages['outage_start']) raw_outages['outage_end'] = pd.to_datetime(raw_outages['outage_end'])
3. 给每条线路生成状态标记列
核心逻辑就是:对每条线路,找出所有落在中断时间段内的时间戳,标记为0;其余正常时间戳标记为1。这里给你两种实现方式,按需选择:
方式一:简洁版(适合中小数据量)
用pd.IntervalIndex来快速判断时间戳是否在中断区间内:
# 获取所有唯一的线路编号 unique_lines = raw_outages['line_id'].unique() for line in unique_lines: # 筛选当前线路的所有中断记录 line_outages = raw_outages[raw_outages['line_id'] == line] # 创建中断时间区间的索引 outage_intervals = pd.IntervalIndex.from_arrays(line_outages['outage_start'], line_outages['outage_end'], closed='both') # 逐个判断时间戳是否在中断区间,是则0,否则1 time_df[line] = np.where(time_df['timestamp'].apply(lambda x: any(x in interval for interval in outage_intervals)), 0, 1)
方式二:高效向量化版(适合大数据量)
全年有50多万条时间戳,大数据量下用向量化操作会快很多:
unique_lines = raw_outages['line_id'].unique() for line in unique_lines: line_outages = raw_outages[raw_outages['line_id'] == line] # 先初始化全1的数组(默认正常状态) line_status = np.ones(len(time_df), dtype=int) # 遍历每个中断区间,把对应时间戳标记为0 for _, row in line_outages.iterrows(): mask = (time_df['timestamp'] >= row['outage_start']) & (time_df['timestamp'] <= row['outage_end']) line_status[mask] = 0 # 把状态列加入到目标DataFrame time_df[line] = line_status
4. 最终效果
跑完上面的代码,time_df就是你要的目标DataFrame了:第一列是timestamp(全年每分钟的时间戳),其余列是各线路的状态——1代表正常,0代表处于中断事件中。
小提醒
- 如果同一条线路有重叠的中断时间段,上面的方法依然有效,只要落在任何一个中断区间就会被标记为0。
- 要是处理闰年,只需要调整
start_date和end_date为对应闰年的日期就行。 - 数据量较大时,优先用方式二,速度会快不少。
内容的提问来源于stack exchange,提问作者user1047
相关产品推荐
相关产品推荐

