Python中用If语句匹配上下行值时未找到全部匹配的问题排查
问题:Python数据匹配代码仅返回部分结果,疑or运算符使用有误
import pandas as pd import numpy as np df= pd.read_csv ("file.csv") n = 0 a = 7 # 1st value to find in row1 b = 39 # 2nd value to find in row2 c = 10 # 3rd value to find in row3 d = 38 # 4th value to find in row4 value_1 = 5 value_2 = 21 while n < len(df)-1 : if df.loc[n].isin([a]).any # 7 is in any in n row if df.loc[n+1].isin([b]).any(): #39 is in any in n+1 row if df.loc[n+2].isin([c]).any(): #10 is in any in n+2 row if df.loc[n+3].isin([d]).any(): #44 is in any in n+3 row if df.loc[n].isin([value_1]).any(): if (df.loc[n].isin([value_2 ]).any() or df.loc[n-1].isin([value_2 ]).any() or df.loc[n+1].isin([value_2 ]).any()): display (df.loc[n:n]) elif df.loc[n+1].isin([value_1]).any() : if (df.loc[n+1].isin([value_2 ]).any() or df.loc[n].isin([value_2 ]).any() or df.loc[n+1].isin([value_2 ]).any()): display (df.loc[n:n]) elif df.loc[n-1].isin([value_1]).any() : if (df.loc[n-1].isin([value_2 ]).any() or df.loc[n-2].isin([value_2 ]).any() or df.loc[n].isin([value_2 ]).any()): display (df.loc[n:n])
需求说明
- 先找到连续四行:第n行含
a,n+1行含b,n+2行含c,n+3行含d - 检查
value_1是否出现在第n行、n-1行或n+1行中 - 若
value_1存在,需确认value_2出现在该value_1所在行或其上下行中 - 满足条件则显示对应行
问题现状
代码运行后仅返回部分匹配结果,示例数据如下:
A B C D E F 1 | 4 5 8 16 5 44 #VALUE_1 (5) 2 | 1 4 12 15 22 21 #VALUE_2 (21) 3 | 2 11 13 15 28 33 4 | 5 15 29 35 7 33 5 | 6 7 39 12 14 16 6 | 1 9 10 12 20 26 7 | 6 38 20 36 33 34 8 | 12 21 7 28 35 39 9 | 5 18 39 33 35 36 10| 4 7 10 18 19 28 11| 3 4 15 19 28 38
示例中第4-7行满足连续四行匹配条件,value_1(5)在第4行,需检查value_2(21)是否在第3、4、5行中,满足条件应显示对应行,但代码未正确捕获这类情况。
分析与解决方案
问题根源
- 语法错误:第一个
if语句df.loc[n].isin([a]).any缺少括号,应为.any(),直接导致部分逻辑未执行或报错。 - elif逻辑限制:使用
elif会导致只要前一个条件满足,后续条件就被跳过。比如如果n行和n+1行同时存在value_1,只会检查第一个条件,漏掉第二种情况。 - 边界索引错误:
- 循环条件
n < len(df)-1错误,需访问n+3行,循环上限应为len(df)-3,否则会出现索引越界。 - 当
n=0时,n-1=-1,访问df.loc[-1]会触发错误,未处理边界情况。
- 循环条件
- 逻辑冗余与错误:第二个
elif中重复判断df.loc[n+1].isin([value_2]).any(),且部分条件未覆盖需求场景。
修正后的代码
import pandas as pd import numpy as np df = pd.read_csv("file.csv") a = 7 b = 39 c = 10 d = 38 value_1 = 5 value_2 = 21 # 遍历所有合法的n,确保n+3不超出索引范围 for n in range(len(df) - 3): # 检查连续四行的匹配条件 if (df.loc[n].isin([a]).any() and df.loc[n+1].isin([b]).any() and df.loc[n+2].isin([c]).any() and df.loc[n+3].isin([d]).any()): # 收集需要检查value_1的行,避免负索引 check_rows = [] if n > 0: check_rows.append(n-1) check_rows.extend([n, n+1]) # 逐个检查包含value_1的行,验证value_2的存在 for row_idx in check_rows: if df.loc[row_idx].isin([value_1]).any(): # 确定value_2的检查范围,避免索引越界 start = max(0, row_idx - 1) end = min(len(df)-1, row_idx + 1) # 检查范围内是否存在value_2 if df.loc[start:end].isin([value_2]).any().any(): display(df.loc[n:n]) break # 避免重复显示同一n行
关键改进点
- 用
for循环替代while,更清晰且从根源避免索引越界 - 去掉
elif,改用遍历所有可能的value_1出现行,确保不遗漏任何匹配情况 - 增加边界检查,避免访问负索引或超出数据长度的索引
- 简化
value_2的范围检查逻辑,用切片+双重any()实现高效判断
内容的提问来源于stack exchange,提问作者Kan
相关产品推荐
相关产品推荐

