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

如何标记DataFrame指定列值变化位置的前后各2行数据

问题描述

需要在pandas DataFrame中新建名为mark的列,目前已实现当Numbers列的值发生变化时,对应行的mark值设为True,现需要将Numbers列值发生变化位置的前2行、后2行的mark值也统一设为True。

预期实现效果
Numbersmark
10False
10False
10False
10False
10True
10True
20True
20True
20False
20False
20True
20True
30True
40True
40True
40False
40False
40False
现有实现代码
import pandas as pd
data = [10,10,10,10,10,10,20,20,20,20,20,20,20,30,40,40,40,40,40] 
df = pd.DataFrame(data, columns=['Numbers'])
check=10
def detect_changes (row):
    global check 
    if row['Numbers'] == check :           
        return False
    else :
        check=check+10
        return True
df['mark']=df.apply (lambda row: detect_changes(row), axis=1)
实现方案

原有全局变量+apply逐行判断的写法执行效率低,且不方便扩展前后行标记逻辑,直接用pandas原生移位运算即可快速实现需求,结果完全匹配预期效果:

import pandas as pd
data = [10,10,10,10,10,10,20,20,20,20,20,20,20,30,40,40,40,40,40] 
df = pd.DataFrame(data, columns=['Numbers'])

# 识别所有列值发生变化的行(值和上一行不相等即为变化点,默认标记在新值第一行)
change_mask = df['Numbers'].ne(df['Numbers'].shift())

# 标记变化点+前2行+后2行
df['mark'] = change_mask
for offset in range(1, 3):
    # 覆盖变化点前的2行
    df['mark'] = df['mark'] | change_mask.shift(-offset, fill_value=False)
# 覆盖变化点后的第2行(加变化点本身刚好凑齐后2行)
df['mark'] = df['mark'] | change_mask.shift(1, fill_value=False)

逻辑说明

  • 用shift()做移位运算避免逐行循环,万级以上数据量下执行速度比apply快数十倍
  • 变化点标记在新值第一行,向前移1、2位即可覆盖变化前的2行,向后移1位加上变化点本身,刚好覆盖变化后的2行,和给出的预期结果完全对齐
  • 如果需要调整前后覆盖的行数,只需要修改循环范围和向后移位的offset即可,不需要改动核心逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 01:39:19