You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Pandas检测DataFrame中无匹配后续Tx的重复Rx记录

问题描述

现有包含Time、Code、Id三列的Pandas DataFrame,样例数据如下:

TimeCodeId
10:10:00Rx11
10:10:01Tx11
10:10:02Rx12
10:10:04Tx12
10:10:06Rx13
10:10:07Tx13
10:10:08Rx11
10:10:10Rx11

校验规则:

  • 所有Code值为Rx的记录,紧邻的下一条记录必须是相同Id的Tx记录
  • 若出现连续同Id的Rx记录,仅判定第一条Rx为异常行,后续重复Rx属于冗余记录直接剔除
  • 样例预期输出为10:10:08、Id=11的Rx异常行,10:10:10的同Id Rx为冗余记录不输出

原有基于iterrows()的逐行循环实现效率低,需用Pandas原生向量化操作替代,不使用显式for循环完成需求。

原有循环实现参考:

old_cell = None
for index, row in pdo_df.iterrows():
    if old_cell is None:
        old_cell = row
    if row['Function_code'] == old_cell['Function_code']:
        print("----------------")
        print("Error :")
        print(old_cell)
        print(row)
        print("----------------")
    old_cell = row
实现方案

使用Pandas内置shift移位方法实现全向量化判断,无显式循环,性能相比iterrows提升1~2个数量级,适配十万级以上大数据量场景。

注:如果实际列名为Function_code,将代码中Code字段替换为对应列名即可直接运行。

完整实现代码:

import pandas as pd

# 构造样例数据
df = pd.DataFrame([
    ["10:10:00", "Rx", 11],
    ["10:10:01", "Tx", 11],
    ["10:10:02", "Rx", 12],
    ["10:10:04", "Tx", 12],
    ["10:10:06", "Rx", 13],
    ["10:10:07", "Tx", 13],
    ["10:10:08", "Rx", 11],
    ["10:10:10", "Rx", 11]
], columns=["Time", "Code", "Id"])

# 批量获取每一行下一条记录的Code和Id值
next_code = df['Code'].shift(-1)
next_id = df['Id'].shift(-1)

# 构造异常判断条件:当前行是Rx,下一行同Id 且 下一行不是Tx
error_mask = (df['Code'] == 'Rx') & (next_id == df['Id']) & (next_code != 'Tx')
# 筛选得到异常Rx行
error_rows = df[error_mask]

print(error_rows)

运行输出结果和预期完全一致:

Time Code  Id
6  10:10:08   Rx  11
扩展说明
  • 所有判断逻辑均为Pandas底层C实现的向量化运算,避免了Python层面逐行循环的性能开销
  • 如果需要识别「最后一条记录为Rx、后续无任何记录」的边界异常,只需要在error_mask中追加或条件即可:
    error_mask = (df['Code'] == 'Rx') & (
        ((next_id == df['Id']) & (next_code != 'Tx')) | next_code.isna()
    )
    
  • 如果需要同时标记冗余的重复Rx行,只需要调整判断条件为「当前行是Rx,上一行同Id且也是Rx」即可筛选出冗余记录。

内容的提问来源于stack exchange,提问作者Dryade

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 04:54:12