
本文教你使用 pandas 实现多行顺序匹配(如 a→b→c→d 连续四行出现)与邻近行条件判断(value_1 所在行及其上下行中是否存在 value_2),避免 while 循环和索引越界错误,提升可读性与鲁棒性。
本文教你使用 pandas 实现多行顺序匹配(如 a→b→c→d 连续四行出现)与邻近行条件判断(value_1 所在行及其上下行中是否存在 value_2),避免 while 循环和索引越界错误,提升可读性与鲁棒性。
在数据分析中,常需识别具有空间/时序结构的模式——例如:某值 a 出现在第 n 行,b 紧随其后出现在第 n+1 行,c 在 n+2 行,d 在 n+3 行;满足该“垂直序列”后,进一步检查 value_1 是否位于 n、n−1 或 n+1 行,并确认 value_2 是否出现在 value_1 所在行或其紧邻上下行(共 3 行窗口)。原始代码存在多个关键问题:isin().any 误用于标量检查、缺少边界防护导致 IndexError(如 n-1 在首行越界)、逻辑嵌套过深且 or 条件未覆盖所有有效组合。
以下是优化后的专业实现方案:
✅ 正确思路与核心改进
-
用
in row.values替代isin([x]).any():更简洁、语义清晰,避免 Series 比较陷阱; -
严格边界控制:主循环上限设为
len(df) - 3,确保i+3不越界;子循环使用max(0, j-1)和min(len(df), j+2)防止负索引或超尾; -
分层扫描,解耦逻辑:先定位
a-b-c-d序列起始行i,再在[i−1, i, i+1]中找value_1的行j,最后在[j−1, j, j+1]中查value_2的行k; -
结果输出更实用:返回完整匹配的上下文行(如
df.loc[j-1:j+1]),而非仅当前行。
✅ 完整可运行代码示例
import pandas as pd
# 示例数据(对应问题中的表格)
data = {
'A': [4, 1, 2, 5, 6, 1, 6, 12, 5, 4, 3],
'B': [5, 4, 11, 15, 7, 9, 38, 21, 18, 7, 4],
'C': [8, 12, 13, 29, 39, 10, 20, 7, 39, 10, 15],
'D': [16, 15, 15, 35, 12, 12, 36, 28, 33, 18, 19],
'E': [5, 22, 28, 7, 14, 20, 33, 35, 35, 19, 28],
'F': [44, 21, 33, 33, 16, 26, 34, 39, 36, 28, 38]
}
df = pd.DataFrame(data, index=range(1, 12)) # 行索引从 1 开始,便于对照问题描述
# 定义目标值
a, b, c, d = 7, 39, 10, 38
value_1, value_2 = 5, 21
matches = [] # 存储所有匹配的上下文片段
for i in range(len(df) - 3): # 确保 i+3 合法
if (a in df.iloc[i].values and
b in df.iloc[i + 1].values and
c in df.iloc[i + 2].values and
d in df.iloc[i + 3].values):
# 在 [i-1, i, i+1] 行中搜索 value_1
for j in range(max(0, i - 1), min(len(df), i + 2)):
if value_1 in df.iloc[j].values:
# 在 [j-1, j, j+1] 行中搜索 value_2
for k in range(max(0, j - 1), min(len(df), j + 2)):
if value_2 in df.iloc[k].values:
# 记录 value_1 所在行 j 及其上下文(3 行)
context_start = max(0, j - 1)
context_end = min(len(df), j + 2)
matches.append(df.iloc[context_start:context_end].copy())
break # 找到一个 value_2 即可,避免重复添加同一上下文
break # 找到 value_1 后跳出内层循环
# 输出结果
if matches:
print(f"共找到 {len(matches)} 组匹配上下文:\n")
for idx, ctx in enumerate(matches, 1):
print(f"▶ 匹配 {idx}(value_1={value_1} 在第 {ctx.index[1]} 行,value_2={value_2} 在邻近行):")
print(ctx)
print("-" * 40)
else:
print("未找到符合条件的匹配模式。")⚠️ 关键注意事项
-
索引 vs 位置:
df.loc[i]基于标签索引(若 CSV 无指定索引则为整数),而df.iloc[i]基于位置索引(推荐用于循环,避免因自定义索引导致意外行为); -
重复匹配处理:同一
value_1行可能被多个a-b-c-d序列触发,代码中使用break避免重复记录相同上下文; -
性能提示:对超大数据集,可预计算每行的
set(row.values)提升in查找效率; -
扩展性建议:将
a,b,c,d封装为列表pattern = [7,39,10,38],用all(pattern[j] in df.iloc[i+j].values for j in range(len(pattern)))实现动态长度匹配。
该方案兼顾正确性、可维护性与教学清晰度,是 Pandas 行级模式挖掘的典型实践范式。

















