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

Pandas DataFrame二进制序列转态识别:代码原理与优化问询

原代码运行原理

你的代码按CLI_CD分组处理每个客户的独立序列,核心逻辑拆解如下:

  1. 定位连续6个0的窗口:df['TARGET'].rolling(6).sum().eq(0)
    • 对TARGET列做窗口大小为6的向前滚动求和,当窗口内所有值都是0时,求和结果为0,此时返回True。这一步会标记出连续6个0窗口的最后一行。
  2. 映射到目标行:.shift(-6)
    • 将上一步得到的True向前移位6位,把连续6个0窗口的起始前一行(即需要标记的行)对应过来。比如第7-12行全为0,rolling(6).sum()会在第12行返回True,shift(-6)会把这个True放到第6行的位置。
  3. 筛选当前行是1的情况:& df['TARGET'].eq(1)
    • 只有当目标行的TARGET值为1时,OUTPUT列才会标记为True,精准匹配你“当前行是1,且之后连续6行都是0”的需求。
原代码的合理性与优化方案

合理性验证

  • 分组逻辑正确:按CLI_CD分组避免了不同客户的行互相干扰,符合业务场景。
  • 需求匹配准确:通过滚动求和+移位操作,完美实现了“标记最后一个满足后续6行全0的1所在行”的要求。

优化实现(更直观高效)

原代码的向前窗口+移位写法稍显绕,可改为更直观的向后窗口写法,同时保留Pandas向量化操作的性能优势:

def verify(df):
    # 检查当前行之后的1-6行是否全为0:shift(-1)取到下一行,rolling(6)覆盖后续6行,min_periods=6确保必须有完整6行
    has_6_zeros_after = df['TARGET'].shift(-1).rolling(6, min_periods=6).sum().eq(0)
    # 同时满足当前行TARGET为1
    df['OUTPUT'] = df['TARGET'].eq(1) & has_6_zeros_after
    return df

df = df.groupby('CLI_CD').apply(verify)

性能提升建议

如果数据集规模较大,可直接用groupby结合原生滚动操作替代自定义函数,减少额外开销:

df['OUTPUT'] = df.groupby('CLI_CD').apply(
    lambda x: x['TARGET'].eq(1) & x['TARGET'].shift(-1).rolling(6, min_periods=6).sum().eq(0)
).reset_index(level=0, drop=True)
边界情况处理说明
  • 组内末尾行:如果某行是组内倒数第6行及以后,后续不足6行,has_6_zeros_after会返回False,符合需求(无连续6行0的条件不成立)。
  • 连续1的场景:比如第5、6行都是1,后续7-12行全为0——此时只有第6行的OUTPUT会标记为True,因为它是最后一个满足后续6行全0的1,完全匹配你的要求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 17:03:30