Pandas:计算事件周围时间序列数据的平均行为
Pandas: calculating average behaviour of time series data around an event
我有两个带有日期时间信息的数据框,df_stream
是事件流,df_events
是时间上的特定事件。例如:
蓝色是流,红色线是事件。 window 是 30min
事件的任一侧,时间粒度是 30s
.
如何生成给定时间 window 和时间粒度内所有事件流的平均行为的数据帧/图表?
流数据帧如下所示:
streamEventId
DateTime
2020-08-20 10:39:24 44791313
2020-08-20 10:40:30 44791721
2020-08-20 10:40:54 44694121
2020-08-20 10:41:16 44902962
2020-08-20 10:42:04 44622569
事件数据框如下所示:
DateTime
0 2020-11-17 09:49:00
1 2020-11-17 10:49:00
2 2020-11-17 11:11:00
3 2020-11-17 11:16:00
4 2020-11-17 12:11:00
我已经设法打印了每个事件的图表,并打印了各自的 windows,但我很难将逻辑结合起来。我也使用 iterrows
,我不喜欢它。
我目前的做法:
for i in df_events[["DateTime"]].iterrows():
date_time = i[1].values[0]
before = date_time - pd.Timedelta(window)
after = date_time + pd.Timedelta(window)
df_stream_temp = df_stream.loc[before:after].copy()
plt.figure(figsize=(20, 2))
df_stream_mva = (
df_stream.streamEventId.groupby(pd.Grouper(freq="30s"))
.count()
.loc[before:after]
)
y_height = df_stream_mva.max()
ax = df_stream_mva.plot()
plt.vlines(df_events.DateTime.to_list(), 0, y_height, color="lightcoral")
ax.set_ylim([0, y_height])
这给出了一系列不错的图表:
等等...
我想计算并绘制上面的平均值和置信区间。
坐下来解决问题。
使用与我上面的 iterrows
示例类似的逻辑,我遍历了 df_events
,创建了 before
和 after
时间 window 限制并使用了这些过滤按给定时间频率分组的 df_stream
。然后使用时间增量索引重新计算索引以获得“与事件的距离”索引。然后将其附加到列表中,然后使用 pd.concat
和轴 1 组合。示例如下:
window = "30 min"
freq = "30s"
collect_list = []
for i in df_events[["DateTime"]].iterrows():
date_time = i[1].values[0]
before = date_time - pd.Timedelta(window)
after = date_time + pd.Timedelta(window)
df_stream_window = (
df_stream.streamEventId.groupby(pd.Grouper(freq=freq))
.count()
.loc[before:after]
.reset_index()
.rename(columns={"streamEventId": "stream events"})
)
df_stream_window = df_stream_window.set_index(
pd.to_timedelta((df_stream_window.DateTime - pd.to_datetime(date_time)))
/ np.timedelta64("1", "m")
)
collect_list.append(df_stream_window)
df_collect = pd.concat(collect_list, axis=1)
这生成了以下数据框:
DateTime stream events DateTime \
DateTime
-30.0 2020-11-17 09:19:00 5 2020-11-17 10:19:00
-29.5 2020-11-17 09:19:30 5 2020-11-17 10:19:30
-29.0 2020-11-17 09:20:00 3 2020-11-17 10:20:00
-28.5 2020-11-17 09:20:30 2 2020-11-17 10:20:30
-28.0 2020-11-17 09:21:00 3 2020-11-17 10:21:00
stream events DateTime stream events \
DateTime
-30.0 3 2020-11-17 10:41:00 6
-29.5 5 2020-11-17 10:41:30 6
-29.0 3 2020-11-17 10:42:00 4
-28.5 3 2020-11-17 10:42:30 1
-28.0 1 2020-11-17 10:43:00 4
....
然后可以在 Seaborn 中使用 estimator="mean"
绘图:
ax = sns.lineplot(data=df_collect, estimator="mean")
plt.axvline(0, color="lightcoral")
ax.set_xlabel("Time before / after event (min)")
ax.set_ylabel("# Stream Events")
我有两个带有日期时间信息的数据框,df_stream
是事件流,df_events
是时间上的特定事件。例如:
蓝色是流,红色线是事件。 window 是 30min
事件的任一侧,时间粒度是 30s
.
如何生成给定时间 window 和时间粒度内所有事件流的平均行为的数据帧/图表?
流数据帧如下所示:
streamEventId
DateTime
2020-08-20 10:39:24 44791313
2020-08-20 10:40:30 44791721
2020-08-20 10:40:54 44694121
2020-08-20 10:41:16 44902962
2020-08-20 10:42:04 44622569
事件数据框如下所示:
DateTime
0 2020-11-17 09:49:00
1 2020-11-17 10:49:00
2 2020-11-17 11:11:00
3 2020-11-17 11:16:00
4 2020-11-17 12:11:00
我已经设法打印了每个事件的图表,并打印了各自的 windows,但我很难将逻辑结合起来。我也使用 iterrows
,我不喜欢它。
我目前的做法:
for i in df_events[["DateTime"]].iterrows():
date_time = i[1].values[0]
before = date_time - pd.Timedelta(window)
after = date_time + pd.Timedelta(window)
df_stream_temp = df_stream.loc[before:after].copy()
plt.figure(figsize=(20, 2))
df_stream_mva = (
df_stream.streamEventId.groupby(pd.Grouper(freq="30s"))
.count()
.loc[before:after]
)
y_height = df_stream_mva.max()
ax = df_stream_mva.plot()
plt.vlines(df_events.DateTime.to_list(), 0, y_height, color="lightcoral")
ax.set_ylim([0, y_height])
这给出了一系列不错的图表:
等等...
我想计算并绘制上面的平均值和置信区间。
坐下来解决问题。
使用与我上面的 iterrows
示例类似的逻辑,我遍历了 df_events
,创建了 before
和 after
时间 window 限制并使用了这些过滤按给定时间频率分组的 df_stream
。然后使用时间增量索引重新计算索引以获得“与事件的距离”索引。然后将其附加到列表中,然后使用 pd.concat
和轴 1 组合。示例如下:
window = "30 min"
freq = "30s"
collect_list = []
for i in df_events[["DateTime"]].iterrows():
date_time = i[1].values[0]
before = date_time - pd.Timedelta(window)
after = date_time + pd.Timedelta(window)
df_stream_window = (
df_stream.streamEventId.groupby(pd.Grouper(freq=freq))
.count()
.loc[before:after]
.reset_index()
.rename(columns={"streamEventId": "stream events"})
)
df_stream_window = df_stream_window.set_index(
pd.to_timedelta((df_stream_window.DateTime - pd.to_datetime(date_time)))
/ np.timedelta64("1", "m")
)
collect_list.append(df_stream_window)
df_collect = pd.concat(collect_list, axis=1)
这生成了以下数据框:
DateTime stream events DateTime \
DateTime
-30.0 2020-11-17 09:19:00 5 2020-11-17 10:19:00
-29.5 2020-11-17 09:19:30 5 2020-11-17 10:19:30
-29.0 2020-11-17 09:20:00 3 2020-11-17 10:20:00
-28.5 2020-11-17 09:20:30 2 2020-11-17 10:20:30
-28.0 2020-11-17 09:21:00 3 2020-11-17 10:21:00
stream events DateTime stream events \
DateTime
-30.0 3 2020-11-17 10:41:00 6
-29.5 5 2020-11-17 10:41:30 6
-29.0 3 2020-11-17 10:42:00 4
-28.5 3 2020-11-17 10:42:30 1
-28.0 1 2020-11-17 10:43:00 4
....
然后可以在 Seaborn 中使用 estimator="mean"
绘图:
ax = sns.lineplot(data=df_collect, estimator="mean")
plt.axvline(0, color="lightcoral")
ax.set_xlabel("Time before / after event (min)")
ax.set_ylabel("# Stream Events")