带重叠事件的稀疏时间序列时间区间总时长计算方法咨询
更简洁安全的实现方案
你原来的核心思路是对的,我们可以换个更直接的逻辑:相邻两个事件的时间间隔内,亮灯的数量是固定的,只要这个数量大于0,就把这段时间差计入总时长,完全不需要做切换点配对,天然避免边界问题:
import pandas as pd # 转换事件标记、计算累计亮灯数量 df["event_flag"] = df["事件(开/关)"].map({"on": 1, "off": -1}) df["cumulative_lit"] = df["event_flag"].cumsum() # 计算相邻事件的时间差 df["time_diff"] = df["时间(秒)"].diff().shift(-1) # 筛选亮灯数大于0的区间,求和时间差得到总时长 total_time = df.loc[df["cumulative_lit"] > 0, "time_diff"].sum()
用你给出的示例数据测试,得到的结果是12秒,和实际亮灯总时长完全匹配。
边界场景处理
上面的核心代码默认统计的是「第一个事件到最后一个事件之间的亮灯时长」,如果需要覆盖更复杂的场景,只需要加少量逻辑即可:
- 事件记录不是从全灭状态开始:比如你开始记录时已经有2盏灯亮,只需要在计算累计亮灯数时加上初始值即可:
initial_lit = 2 # 替换为实际初始亮灯数 df["cumulative_lit"] = df["event_flag"].cumsum() + initial_lit - 需要统计到最后一个事件之后的时间:比如你要统计从0时刻到20秒的总亮灯时长,只需要补上首尾的额外判断:
start_time = 0 end_time = 20 # 补初始时间段的亮灯时长 if initial_lit > 0: total_time += df["时间(秒)"].iloc[0] - start_time # 补结束时间段的亮灯时长 if df["cumulative_lit"].iloc[-1] > 0: total_time += end_time - df["时间(秒)"].iloc[-1]
原有方案的修补方式
如果你不想更换现有思路,只需要补上切换点的边界判断即可解决问题:
df["event_flag"] = df["Event (on/off)"].map({"on": 1, "off": -1}) df["cumulative"] = df["event_flag"].cumsum() df["cumulative"] = df.apply(lambda x: 1 if x >= 1 else 0) switch_rows = df["Time (s)"][df["cumulative"].diff != 0].tolist() # 补开头判断:如果第一个事件发生时已经是亮灯状态,插入起始时间 if df["cumulative"].iloc[0] == 1: switch_rows.insert(0, 0) # 0可替换为你需要的统计起始时间 # 补结尾判断:如果切换点数量为奇数,说明结束时还在亮灯,插入结束时间 end_time = df["Time (s)"].iloc[-1] # 可替换为自定义统计结束时间 if len(switch_rows) % 2 == 1: switch_rows.append(end_time) total_time = 0 for i in range(0, len(switch_rows), 2): total_time += switch_rows[i+1] - switch_rows[i]
内容的提问来源于stack exchange,提问作者Apollo42
相关产品推荐
相关产品推荐

