如何在Pandas中按多条件移除连续重复行并更新Departure字段
解决Pandas中连续重复行的合并问题
问题描述
给定如下Pandas DataFrame:
import pandas as pd df = pd.DataFrame( [ ['China', 'L', '08/06/2022 20:00', '08/10/2022 20:00'], ['China', 'L', '8/13/2022 00:54', '8/14/2022 00:54'], ['China', 'M', '8/14/2022 00:54', '8/14/2022 12:54'], ['United Kingdom', 'L', '8/27/2022 06:36', '8/31/2022 21:08'], ['United Kingdom', 'L', '9/01/2022 21:08', '09/02/2022 21:38'], ['China', 'D', '09/04/2022 21:38', '09/06/2022 21:38'] ], columns=['Country', 'Function', 'Arrival', 'Departure'] )
需要实现以下处理:
- 移除连续重复的行,非连续的重复行不处理
- 若
Function列值变化,即使行连续也不算重复行 - 合并连续重复行时,保留第一行的
Country、Function、Arrival,将Departure替换为该组最后一行的对应值
处理后的目标DataFrame如下:
df = pd.DataFrame( [ ['China', 'L', '08/06/2022 20:00', '8/14/2022 00:54'], ['China', 'M', '8/14/2022 00:54', '8/14/2022 12:54'], ['United Kingdom', 'L', '8/27/2022 06:36', '09/02/2022 21:38'], ['China', 'D', '09/04/2022 21:38', '09/06/2022 21:38'] ], columns=['Country', 'Function', 'Arrival', 'Departure'] )
解决方案
可以通过标记连续分组、分组聚合的方式实现:
import pandas as pd # 原始数据 df = pd.DataFrame( [ ['China', 'L', '08/06/2022 20:00', '08/10/2022 20:00'], ['China', 'L', '8/13/2022 00:54', '8/14/2022 00:54'], ['China', 'M', '8/14/2022 00:54', '8/14/2022 12:54'], ['United Kingdom', 'L', '8/27/2022 06:36', '8/31/2022 21:08'], ['United Kingdom', 'L', '9/01/2022 21:08', '09/02/2022 21:38'], ['China', 'D', '09/04/2022 21:38', '09/06/2022 21:38'] ], columns=['Country', 'Function', 'Arrival', 'Departure'] ) # 1. 创建连续分组键:当Country或Function与上一行不同时,分组编号+1 group_key = (df[['Country', 'Function']] != df[['Country', 'Function']].shift()).any(axis=1).cumsum() # 2. 分组聚合:保留组内第一行的Country、Function、Arrival,取最后一行的Departure result_df = df.groupby(group_key).agg( Country=('Country', 'first'), Function=('Function', 'first'), Arrival=('Arrival', 'first'), Departure=('Departure', 'last') ).reset_index(drop=True) print(result_df)
代码解释
创建分组键:
- 使用
shift()获取上一行的Country和Function,与当前行对比,只要其中一个字段不同,就标记为True - 用
cumsum()对这些True值累加,生成连续相同组的唯一编号,这样连续相同的Country+Function会被分到同一组
- 使用
分组聚合:
- 对每个分组,
first()取组内第一行的Country、Function、Arrival last()取组内最后一行的Departurereset_index(drop=True)去掉分组键的索引,恢复原始DataFrame的结构
- 对每个分组,
运行上述代码后,就能得到目标结果。
内容的提问来源于stack exchange,提问作者Lion_YY
相关产品推荐
相关产品推荐

