pandas中如何为DataFrame的连续True序列生成递增编号
可行实现方案
核心逻辑非常明确:识别Steps列中每一段连续True的起始位置,按出现顺序给每段True分配递增编号,False位置填充0即可,以下是两种常用实现:
方案1:纯向量化实现(推荐,性能最优)
全程用pandas内置向量化运算,没有循环,即使是百万行级别的数据也能快速跑完,代码如下:
import pandas as pd # 构造示例数据(你可以替换成自己的实际DataFrame) df = pd.DataFrame({ 'Steps': [False, False, True, True, True, False, True, True, False, False, False, True] }) # 步骤1:标记所有连续True段的起始行:当前行是True、上一行是False(首行默认前序值为False) true_block_start = df['Steps'] & (~df['Steps'].shift(fill_value=False)) # 步骤2:对起始标记累计求和得到段序号,乘原Steps列自动把False位置置为0 df['Numbered'] = true_block_start.cumsum() * df['Steps']
运行后输出结果和预期完全一致:
Steps Numbered 0 False 0 1 False 0 2 True 1 3 True 1 4 True 1 5 False 0 6 True 2 7 True 2 8 False 0 9 False 0 10 False 0 11 True 3
逻辑说明:
shift(fill_value=False)会把Steps列整体下移1行,首行空值填充为False,用来判断上一行的布尔状态- 累计求和
cumsum()每遇到一个True段的起始标记就会加1,自然实现了连续段的递增编号 - 最后乘原布尔列时,True会被转成1、False转成0,一步完成False位置填0的需求。如果不需要给False填0,删掉末尾的
* df['Steps']即可。
方案2:分组循环实现(可读性更高,适合小数据量)
如果更偏向直白的逻辑、不需要处理超大数据,可以先给连续相同值的块打分组id,再遍历分组赋值:
# 给连续相同值的片段分配唯一分组id group_tag = (df['Steps'] != df['Steps'].shift()).cumsum() df['Numbered'] = 0 block_count = 0 # 遍历每个连续值分组 for tag, group in df.groupby(group_tag): # 如果当前分组全是True,序号+1后赋值给组内所有行 if group['Steps'].iloc[0]: block_count += 1 df.loc[group.index, 'Numbered'] = block_count
运行结果和方案1完全一致,因为用到了循环遍历分组,数据量超过10万行时性能会明显比方案1差。
内容的提问来源于stack exchange,提问作者Ralph Bednorz
相关产品推荐
相关产品推荐

