如何统计Event1前后10秒内各类Event2的发生次数?
统计Event1前后10秒内各类Event2的发生次数
问题描述
需要统计每个Event1发生前后10秒内,不同类型Event2的发生次数。数据存储在DataFrame中,包含字段:Subject、Session、Event1Count、Event1Timestamp、Event2Label、Event2Timestamp,其中Event1和Event2记录混存(一条记录要么是Event1,要么是Event2)。目标输出每个Event1对应的Pre-Event1 TypeX(Event1发生前10秒内TypeX的数量)和Post-Event1 TypeX(Event1发生后10秒内TypeX的数量)。
示例输入数据
| Subject | Session | Event1Count | Event1Timestamp | Event2Label | Event2Timestamp |
|---|---|---|---|---|---|
| K1 | 01 | 1 | 476 | NA | NA |
| K1 | 01 | 2 | 2444 | NA | NA |
| K1 | 01 | 3 | 4922 | NA | NA |
| K1 | 01 | NA | NA | Type1 | 483 |
| K1 | 01 | NA | NA | Type1 | 2448 |
| K1 | 01 | NA | NA | Type2 | 2452 |
| K1 | 01 | NA | NA | Type2 | 4920 |
| L2 | 01 | 1 | 35 | NA | NA |
| L2 | 01 | 2 | 310 | NA | NA |
| L2 | 01 | 3 | 1933 | NA | NA |
| L2 | 02 | NA | NA | Type 2 | 30 |
| L2 | 02 | NA | NA | Type 2 | 32 |
| L2 | 02 | NA | NA | Type 2 | 305 |
| L2 | 02 | NA | NA | Type 1 | 1941 |
| K1 | 02 | 1 | 131 | NA | NA |
| K1 | 02 | 2 | 659 | NA | NA |
| K1 | 02 | 3 | 3802 | NA | NA |
| K1 | 02 | NA | NA | Type1 | 137 |
| K1 | 02 | NA | NA | Type1 | 657 |
| K1 | 02 | NA | NA | Type1 | 665 |
目标输出
| Subject | Session | Event1Count | Pre-Event1 Type1 | Post-Event1 Type1 | Pre-Event1 Type2 | Post-Event1 Type2 |
|---|---|---|---|---|---|---|
| K1 | 01 | 1 | 0 | 1 | 0 | 0 |
| K1 | 01 | 2 | 0 | 1 | 0 | 1 |
| K1 | 01 | 3 | 1 | 0 | 0 | 0 |
| L2 | 01 | 1 | 0 | 0 | 2 | 0 |
| L2 | 01 | 2 | 0 | 0 | 1 | 0 |
| L2 | 01 | 3 | 0 | 1 | 0 | 0 |
| K1 | 02 | 1 | 0 | 1 | 0 | 0 |
| K1 | 02 | 2 | 1 | 1 | 0 | 0 |
| K1 | 02 | 3 | 0 | 0 | 0 | 0 |
解决方案
核心思路是拆分Event1和Event2数据集,按Subject+Session分组后,为每个Event1匹配同组内的Event2,再根据时间窗口统计数量。
步骤1:拆分并预处理数据集
将原DataFrame拆分为Event1和Event2两个独立数据集,同时统一Event2的标签格式(避免空格导致统计错误):
import pandas as pd # 假设原数据存储在df中 # df = pd.read_csv("your_data_source.csv") # 拆分Event1数据集:保留含Event1Count的记录 event1_df = df.dropna(subset=["Event1Count"]).reset_index(drop=True) event1_df = event1_df[["Subject", "Session", "Event1Count", "Event1Timestamp"]] # 拆分Event2数据集:保留含Event2Label的记录 event2_df = df.dropna(subset=["Event2Label"]).reset_index(drop=True) # 统一标签格式:去掉空格 event2_df["Event2Label"] = event2_df["Event2Label"].str.replace(" ", "") event2_df = event2_df[["Subject", "Session", "Event2Label", "Event2Timestamp"]]
步骤2:统计每个Event1的时间窗口内Event2数量
通过关联同组数据,标记Event2属于Pre/Post窗口,最后用透视表统计数量:
# 按Subject和Session关联Event1与Event2 merged_df = pd.merge( event1_df, event2_df, on=["Subject", "Session"], how="left" ) # 标记Event2是否在Event1的Pre/Post时间窗口内 merged_df["Pre"] = merged_df.apply( lambda row: 1 if (row["Event1Timestamp"] - 10 <= row["Event2Timestamp"] < row["Event1Timestamp"]) else 0, axis=1 ) merged_df["Post"] = merged_df.apply( lambda row: 1 if (row["Event1Timestamp"] <= row["Event2Timestamp"] <= row["Event1Timestamp"] + 10) else 0, axis=1 ) # 透视表统计各类型Event2的Pre/Post数量 result_df = merged_df.pivot_table( index=["Subject", "Session", "Event1Count"], columns=["Event2Label"], values=["Pre", "Post"], aggfunc="sum", fill_value=0 ) # 重命名列以匹配目标格式 result_df.columns = [f"{col[0]}-Event1 {col[1]}" for col in result_df.columns] result_df = result_df.reset_index() # 补充缺失的类型列(示例仅包含Type1/Type2,若有其他类型可扩展) for label in ["Type1", "Type2"]: if f"Pre-Event1 {label}" not in result_df.columns: result_df[f"Pre-Event1 {label}"] = 0 if f"Post-Event1 {label}" not in result_df.columns: result_df[f"Post-Event1 {label}"] = 0 # 调整列顺序匹配目标输出 result_df = result_df[ ["Subject", "Session", "Event1Count", "Pre-Event1 Type1", "Post-Event1 Type1", "Pre-Event1 Type2", "Post-Event1 Type2"] ]
验证结果
运行上述代码后,result_df的结构与数值将完全匹配目标输出。
内容的提问来源于stack exchange,提问作者KaptainKris
相关产品推荐
相关产品推荐

