如何统计DataFrame中A、B列同时为0的连续行并删除不符合范围的行
解决方法
先看正确的实现代码,能满足你删除A、B列同时为0且连续行数<10或>20的行的需求:
import pandas as pd # 构造示例DataFrame df = pd.DataFrame({ 'A': [0, 0, 0, 2, 1], 'B': [4, 0, 0, 0, 1], 'C': [1, 2, 1, 3, 1] }) # 标记A、B同时为0的行 m1 = df['A'].eq(0) & df['B'].eq(0) # 生成连续相同状态的分组键 group_key = m1.ne(m1.shift()).cumsum() # 计算每个分组的连续行数 group_size = df.groupby(group_key).transform('size') # 生成过滤掩码:保留非目标行,或目标行中连续行数在10-20之间的行 mask = ~(m1 & ((group_size < 10) | (group_size > 20))) # 得到结果 out = df[mask] print(out)
运行后输出符合你的期望:
A B C 0 0 4 1 3 2 0 3 4 1 1 1
你的代码问题分析
- 未处理连续行数>20的情况:你的代码只过滤了连续行数≤9的目标行,完全没处理连续行数>20的情况,不符合“小于10或大于20都删除”的需求。
- 示例中理论上应该生效:按你给出的示例数据,你的代码其实应该能删除行1、2,如果你运行后没效果,可能是数据定义错误或者运行环境的索引问题,比如df的索引不是连续的0-4?
关键步骤解释
- 标记目标行:
m1精准定位A、B同时为0的行,后续只针对这些行的连续块做判断。 - 分组连续行:
m1.ne(m1.shift()).cumsum()把连续的相同状态(都是目标行或都不是)的行归为一组,方便统计连续行数。 - 映射分组大小:
transform('size')让每一行都能获取自己所在连续块的长度,避免单独分组计算后再合并的麻烦。 - 过滤逻辑:
~(m1 & ((group_size <10) | (group_size>20)))直接筛选出需要保留的行:要么不是目标行,要么是目标行但连续行数在10-20之间。
内容的提问来源于stack exchange,提问作者Cinecca
相关产品推荐
相关产品推荐

