Python中如何比对DataFrame相邻行值并提取符合条件的完整行
问题说明
现有3000行5列的告警状态数据集,列结构示例如下:
Id Tag_number Creation_time Code Alert_message 1 GH567 17:19.8 MEI001 0 2 GH567 58:33.4 MEI001 0 3 GH567 15:21.6 MEI001 1 4 GH567 59:33.7 MEI001 1 5 HR864 16:23.5 XUY056 0 6 KI964 34:13.6 UYT345 0 7 KI964 55:24.8 UYT345 1 .... 3000 rows
字段规则:
Alert_message:值为1代表对应记录为告警生成状态,值为0代表无告警Creation_time:存储记录生成的日期与时间
提取规则:当某行Alert_message值为0,且其紧邻的下一行Alert_message值为1时,将这两行同时提取到新的DataFrame中,预期输出如下:
Id Tag_number Creation_time Code Alert_message 2 GH567 58:33.4 MEI001 0 3 GH567 15:21.6 MEI001 1 6 KI964 34:13.6 UYT345 0 7 KI964 55:24.8 UYT345 1
原有实现代码:
df1 = df[df.Alert_message.gt(0) | df.Alert_message.shift(-1).gt(0)]
该代码输出不符合预期,会额外提取连续1值的后续行,比如示例中Id=4的行会被错误提取:
Id Tag_number Creation_time Code Alert_message 2 GH567 58:33.4 MEI001 0 3 GH567 15:21.6 MEI001 1 4 GH567 59:33.7 MEI001 1
错误原因
原代码的筛选逻辑存在漏洞:仅判断了「当前行值为1」或「当前行的下一行值为1」两个条件,但没有对值为1的行增加前置校验——也就是值为1的行只有紧接在0值行后面时才需要保留,连续1值序列里除第一个1之外的其他行,都会因为自身值为1被错误纳入筛选结果,这就是Id=4被误提取的原因。
修正方案
调整筛选条件,精准匹配两类需要保留的行:
- 第一类:0转1的0值行,即当前行
Alert_message为0,且下一行Alert_message为1 - 第二类:0转1的起始1值行,即当前行
Alert_message为1,且上一行Alert_message为0
修正后的代码如下:
# 构造筛选掩码 filter_cond = ( (df['Alert_message'].eq(0) & df['Alert_message'].shift(-1).eq(1)) | (df['Alert_message'].eq(1) & df['Alert_message'].shift(1).eq(0)) ) # 筛选得到结果,重置索引 df_result = df[filter_cond].reset_index(drop=True)
用提供的示例数据运行上述代码,会准确提取Id为2、3、6、7的四行记录,不会误提取连续1值的后续行,输出结果和预期完全一致。
内容的提问来源于stack exchange,提问作者jiah
相关产品推荐
相关产品推荐

