pandas多层索引DataFrame会话组内动态删除连续重复行实现方法
Pandas 分组内连续重复值去重实现方案
核心思路
通过为每个sid分组内的连续相同pageid生成统一分组标记,仅保留每个连续重复组的指定条数数据,仅需1次位移操作即可适配任意长度的连续重复场景,无需多次调用.shift()。
基础实现(连续重复仅保留1条,匹配示例期望结果)
import pandas as pd # 构造示例数据 i = pd.MultiIndex.from_arrays( [[1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3], ['ABC', 'ABC', 'ABC', 'ABC', 'DEF', 'DEF', 'DEF', 'DEF', 'GHI', 'GHI', 'GHI', 'GHI']], names=('sid', 'vid') ) df = pd.DataFrame({ 'pageid': ['dog', 'dog', 'dog', 'dog', 'cat', 'cat', 'pig', 'cat', 'pig', 'cat', 'dog', 'dog'] }, index=i) # 核心处理逻辑 # 每个sid分组内,标记与上一行pageid不相等的行(即连续重复组的第一行) mask = df.groupby('sid', group_keys=False)['pageid'].apply(lambda x: x.ne(x.shift())) result = df[mask] print(result)
运行输出与期望结果完全一致:
pageid sid vid 1 ABC dog 2 DEF cat DEF pig DEF cat 3 GHI pig GHI cat GHI dog
扩展实现(支持保留连续重复的前n条)
如果需要保留最多n条连续重复的记录(比如连续重复最多保留2条),可以通过分组内计数实现,适配任意连续重复长度、任意保留条数需求:
n = 2 # 自定义连续重复最多保留的条数 # 生成连续相同pageid的分组标记 df['group_flag'] = df.groupby('sid', group_keys=False)['pageid'].apply(lambda x: x.ne(x.shift()).cumsum()) # 生成每个连续分组内的行号 df['row_in_group'] = df.groupby(['sid', 'group_flag'], group_keys=False).cumcount() + 1 # 筛选保留前n条,删除临时列 result = df[df['row_in_group'] <= n].drop(columns=['group_flag', 'row_in_group']) print(result)
方案优势
- 无需多次调用
.shift(),即使存在30+条连续重复数据也能高效处理,时间复杂度为线性O(总数据行数) - 兼容多层索引结构,处理过程不会破坏原有的sid、vid索引信息
- 可灵活调整保留的连续重复条数,适配不同业务场景
内容的提问来源于stack exchange,提问作者S44
相关产品推荐
相关产品推荐

