如何在Pandas DataFrame中逐行检查前5行指定列是否含目标字符串?
问题与解决方案
问题描述
我正在处理如下Pandas DataFrame片段:
[Date] [Etype] [IP] [Device] [Event] 1 2020-08-19 23:02:29 Daemon.Emerg xx.xxx.xx.xx True CHASSIS-POWER_STATUS_FAILURE 2 2020-08-19 23:03:57 Daemon.Warning xx.xxx.xx.xx True CHASSIS-TIME_CHANGED_FORWARD 3 2020-08-19 23:03:57 Daemon.Emerg xx.xxx.xx.xx True NTPC-NTP_FIRST_SYNCH_ACHIEVED 4 2020-08-19 23:04:13 Daemon.Alert xx.xxx.xx.xx True CFM-CFM_SERVICE_FAULT_CLEAR 5 2020-08-19 23:06:27 Daemon.Warning xx.xxx.xx.xx True PORT-STATE_CHANGE__R_T需要为每一行检查**前5行(含当前行之前的最多5行)**的
Etype列中是否包含指定字符串(如Daemon.Emerg),实现滑动FIFO式的检查逻辑,希望得到基于索引的实现方案。
解决方案
核心思路:滑动窗口(Rolling Window)
利用Pandas的rolling方法创建固定行数的滑动窗口,结合any()判断窗口内是否存在符合条件的记录,完全基于索引实现,不受时间间隔影响。
实现步骤
方法1:分步实现(清晰易懂)
- 先标记出
Etype列中匹配目标字符串的行:
df['is_emerg'] = df['Etype'].str.contains("Daemon.Emerg")
- 创建大小为5的滑动窗口,检查窗口内是否存在匹配记录:
df['Flag'] = df['is_emerg'].rolling(window=5, min_periods=1).any()
window=5:窗口包含当前行及之前的4行,共5条记录min_periods=1:处理前几行(如第1行无足够前置行)的情况,确保不生成NaN
方法2:简化写法(一步到位)
直接合并两步操作,无需中间列:
df['Flag'] = df['Etype'].str.contains("Daemon.Emerg").rolling(window=5, min_periods=1).any()
扩展:仅检查当前行之前的5行(排除当前行)
如果需求是不包含当前行,只检查前置5行,可通过shift()调整:
df['Flag'] = df['Etype'].str.contains("Daemon.Emerg").shift(1).rolling(window=5, min_periods=0).any().fillna(False)
shift(1):将匹配标记下移一行,避免包含当前行fillna(False):对无前置行的首行填充False
测试结果
用提供的DataFrame测试,最终Flag列结果如下:
| Date | Etype | Flag |
|---|---|---|
| 2020-08-19 23:02:29 | Daemon.Emerg | True |
| 2020-08-19 23:03:57 | Daemon.Warning | True |
| 2020-08-19 23:03:57 | Daemon.Emerg | True |
| 2020-08-19 23:04:13 | Daemon.Alert | True |
| 2020-08-19 23:06:27 | Daemon.Warning | True |
内容的提问来源于stack exchange,提问作者nogcy2k
相关产品推荐
相关产品推荐

