使用Pandas删除同ID下连续重复status的记录
高效移除DataFrame中同ID下连续重复的status记录
问题背景
现有一个已按id、timestamp、status排序的DataFrame,数据如下:
| id | status | timestamp |
|---|---|---|
| 111 | A | 29.08.2023 12:39 |
| 111 | A | 29.08.2023 12:45 |
| 111 | B | 29.08.2023 12:47 |
| 111 | C | 29.08.2023 12:50 |
| 111 | A | 29.08.2023 12:50 |
| 112 | A | 29.08.2023 12:50 |
| 112 | B | 29.08.2023 13:09 |
| 112 | C | 29.08.2023 13:40 |
| 112 | B | 29.08.2023 13:50 |
| 112 | A | 29.08.2023 13:55 |
需求
移除同一id内相邻行中重复的status记录:仅当当前行status与同组前一行相同时移除当前行,非连续的重复status需保留。处理后的目标DataFrame如下:
| id | status | timestamp |
|---|---|---|
| 111 | A | 29.08.2023 12:39 |
| 111 | B | 29.08.2023 12:47 |
| 111 | C | 29.08.2023 12:50 |
| 111 | A | 29.08.2023 12:50 |
| 112 | A | 29.08.2023 12:50 |
| 112 | B | 29.08.2023 13:09 |
| 112 | C | 29.08.2023 13:40 |
| 112 | B | 29.08.2023 13:50 |
| 112 | A | 29.08.2023 13:55 |
由于数据集规模超500万条,逐行对比效率极低,需要高效解决方案。
高效解决方案
利用Pandas的矢量化分组操作实现,底层基于C语言优化,比逐行循环效率高几个数量级,适合百万级数据集:
代码实现
import pandas as pd # 假设原始DataFrame为df # 生成布尔掩码:同一id组内,当前行status与前一行不同,或为组内第一行 mask = df.groupby('id')['status'].transform(lambda x: x != x.shift()) # 应用掩码过滤得到结果 result_df = df[mask]
原理说明
groupby('id'):按id分组,确保仅在同一id范围内对比相邻行x.shift():将每组内的status列向下偏移一行,实现当前行与前一行的status对比x != x.shift():生成布尔值,True表示当前行与前一行status不同(组内第一行因偏移后为NaN,对比结果也为True,会被保留)
注意事项
- 需确保原始DataFrame已按
id和timestamp排序,否则相邻行对比会失去意义 - 该方法无显式循环,所有操作均为矢量化执行,处理500万条数据仅需数秒
内容的提问来源于stack exchange,提问作者Alex_Y
相关产品推荐
相关产品推荐

