如何在Pandas DataFrame中生成布尔型slice列(start到stop为True)
解决方案:无需groupby实现Pandas区间标记
方法1:逐行遍历维护状态(直观易懂)
这种方法通过维护一个状态变量,逐行判断是否处于start到stop的区间内,确保stop所在行也被标记为True:
import pandas as pd df = pd.DataFrame({'start': [True, False, False, False, False, True, False, False, False, False, False, False], 'stop': [False, False, False, True, False, False, True, False, False, False, False, False]}) # 初始化状态和结果列表 in_slice = False slice_col = [] for start_val, stop_val in zip(df['start'], df['stop']): # 遇到start则开启区间 if start_val: in_slice = True # 记录当前行的状态 slice_col.append(in_slice) # 遇到stop则关闭区间(当前行已记录为True) if stop_val: in_slice = False df['slice'] = slice_col
运行后得到的slice列完全符合预期:
start stop slice 0 True False True 1 False False True 2 False False True 3 False True True 4 False False False 5 True False True 6 False True True 7 False False False 8 False False False 9 False False False 10 False False False 11 False False False
方法2:利用累积和实现(无循环,更高效)
如果数据集较大,无循环的向量化方法效率更高,核心是通过构造信号列并计算累积和来标记区间:
# 构造信号:start为1,stop的下一行设为-1(因为stop所在行要包含在区间内) signal = df['start'].astype(int) - df['stop'].shift(-1).fillna(0).astype(int) # 计算累积和,累积和>0的区间即为需要标记的部分 df['slice'] = signal.cumsum() > 0
这个方法的逻辑是:start触发累积和+1,stop的下一行触发累积和-1,这样从start到stop的所有行累积和都大于0,自然被标记为True。
原代码问题分析
你之前的代码df['slice'] = (df['start'] | df.index.isin(range(df['start'].idxmax(), df['stop'].idxmax() + 1)))存在两个关键问题:
idxmax()只会返回第一个True的索引,无法处理多组start-stop区间(比如你的数据中有两组);- 即使只处理单组,
range(a, b+1)的逻辑也会因为df['stop'].idxmax()取的是第一个stop的索引,导致第二组区间完全被忽略,同时逻辑上也没覆盖到所有正确行。
内容的提问来源于stack exchange,提问作者VERBOSE
相关产品推荐
相关产品推荐

