Pandas:如何在分组内无循环统计连续为True的布尔值数量
分组维度下连续布尔True值的无循环统计需求
我找过很多同类问题的解答,这类方法要么无法结合groupby使用,要么不适用于连续布尔值的统计场景。我需要一套无循环的实现方案:在每个分组范围内,统计连续出现的过往True值的累计数量。
测试数据集
用于验证实现效果的pandas数据构造代码如下:
import pandas as pd data = [ [False, 'CLE',], [True, 'CLE'], [True, 'CLE'], [False, 'MON'], [False, 'MON'], [True, 'MON'], [True, 'CLE'], [False, 'CLE'], [False, 'CLE'] ] # 创建pandas DataFrame df = pd.DataFrame(data, columns=["a", "city"])
预期输出结果
每一行对应的统计值输出如下:
0 1 2 0 0 1 3 0 0
已尝试的实现代码
当前写出的尝试代码未达到预期效果,具体代码为:
df['x']=df.a.groupby((df.city!=df.city.shift()).apply(lambda x: x==True).cumsum()).cumcount()
实现方案
全程使用pandas向量化操作,无循环,可直接适配groupby场景,核心逻辑:
- 按城市分组,每遇到一个a为False的位置,就将当前的True累计段编号+1,把连续的True序列拆分为独立的块
- 按城市+累计段编号分组,计算组内的行序号
- 把a为False的位置的计算结果强制置为0,匹配统计规则
具体可运行代码:
# 1. 同city下遇到False时,累计段编号加1 seg = (df['a'] == False).groupby(df['city']).cumsum() # 2. 按city+段编号分组,计算组内序号 df['x'] = df.groupby([df['city'], seg]).cumcount() # 3. a为False的位置,结果置0 df.loc[~df['a'], 'x'] = 0
运行后x列的输出完全匹配预期:
0 0 1 1 2 2 3 0 4 0 5 1 6 3 7 0 8 0 dtype: int64
内容的提问来源于stack exchange,提问作者Danny W
相关产品推荐
相关产品推荐

