对具有重叠事件的稀疏时间序列数据的时间间隔求和

Posted

技术标签:

【中文标题】对具有重叠事件的稀疏时间序列数据的时间间隔求和【英文标题】:Sum time intervals of sparse time-series data with overlapping events 【发布时间】:2022-01-06 23:55:54 【问题描述】:

我有一些按时间排序的数据,用于跟踪不同事件的开始和结束时间。出于说明目的,假设我正在跟踪一组灯泡何时打开和关闭。我的数据结构如下:

Bulb ID Event (on/off) Time (s)
1 on 2
2 on 5
1 off 6
3 on 8
3 off 10
2 off 14

我想找出至少一个灯泡打开的总时间。到目前为止,我最好的想法是更改二进制标志中的 Event 列并对该列执行 cumsum,然后使用 numpy.diffnumpy.where 查找总和从 1 变为 0 或 0 变为 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()

total_time = 0
for i in range(0, len(switch_rows), 2):
    total_time += switch_rows[i+1] - switch_rows[i]

这可行,但不是很安全,因为它假设数据开始和结束时所有灯泡都关闭,但情况不一定如此。有没有更简洁和/或更安全的方法来做到这一点,或者我应该坚持我所拥有的并添加对初始系统状态的检查?

【问题讨论】:

【参考方案1】:

您的解决方案可能有效,但有很多如果和但是。试试pd.pivot_table

pd.pivot_table(data=df,values="Time (s)", columns="Event (on/off)", index="Bulb ID",aggfunc=np.sum)

然后我们可以用它来进一步计算东西。

【讨论】:

这并不能完全给我我想要的东西 - 有了这个,我得到了每个灯泡打开/关闭时的时间戳总和。我想要的是至少一个灯泡打开的总时间,而不是重复计算一个以上的灯泡。【参考方案2】:

我想出了一个使用pandas.resample 的解决方案。我采取了我原来解决方案的前两步,然后只拉出 cumsum 和 time 列,将 time 列设置为 timedelta 索引,然后重新采样为恒定速率,如下所示:

df["event_flag"] = df["Event (on/off)"].map("on": 1, "off": -1)
df["cumulative"] = df["event_flag"].cumsum()

time_data = df[["cumulative"]].set_index(pd.TimedeltaIndex(data=df["Time (s)"], unit="s"))

time_data = time_data.resample("1s").pad()

一旦我有一个恒定的采样率,我就可以计算值非零的行。

total_time = time_data[time_data["cumulative"] != 0].count()

如果我的采样率不是以秒为单位,我可以将这个计数除以我的帧率,例如如果我以 0.2 秒的间隔工作,那么我的总时间是

total_time = 5 * time_data[time_data["cumulative"] != 0].count()

这个解决方案避免了我在第一个解决方案中遇到的问题,而且更实用。

【讨论】:

以上是关于对具有重叠事件的稀疏时间序列数据的时间间隔求和的主要内容,如果未能解决你的问题,请参考以下文章

折叠和合并重叠的时间间隔

熊猫将时间间隔重叠到时间序列

在 Oracle 中对重叠的时间间隔进行分组

如何对稀疏矩阵列表求和?

查找不同行中日期时间间隔的重叠?

SQL按间隔分组,计数和求和