多列时间序列数据移除连续重复项的技术实现问询
移除多列时间序列中的分组内连续重复值(忽略date列)
需求说明
现有如下多列时间序列数据:
date hardware location group rtype value 0 2021-03-01 desk NY opera type-s 0 1 2021-03-01 desk NJ opera type-s 200 2 2021-03-01 desk IL opera type-s 100 3 2022-08-01 desk NY opera type-s 275 4 2021-08-25 desk IL opera type-s 100 5 2022-09-16 desk IL opera type-s 30 6 2022-09-16 desk NY opera type-s 0 7 2022-11-01 desk NJ opera type-s 0 8 2022-11-01 desk IL opera type-s 0
需要实现:
- 忽略
date列 - 按
hardware, location, group, rtype分组,在每个分组内按时间顺序移除连续的重复value(仅保留第一个出现的行) - 最终结果按
date全局排序 - 示例中索引4的行(IL分组的重复value100)需被移除,而索引6的行(NY分组的value0,与索引0的value0不连续)需保留
现有方法问题分析
drop_duplicates方法:- 该方法会删除所有非
date列相同的行(不管是否在分组内连续),导致误删非连续的重复行(如索引6的NY+0行),不符合需求。
- 该方法会删除所有非
直接
shift()比较方法:- 原始数据
date未排序,shift()是按原始索引的相邻行比较,而非分组内的时间顺序相邻行,无法正确识别分组内的连续重复值,因此结果不符合预期。
- 原始数据
可行解决方案
采用groupby+shift()的思路,在每个分组内按时间排序后移除连续重复值,步骤如下:
- 按
hardware, location, group, rtype分组 - 每个分组内按
date排序,确保行按时间顺序排列 - 在分组内筛选出与前一行
value不同的行(保留第一行) - 合并分组结果后按
date全局排序
完整代码实现
import pandas as pd from io import StringIO data = """ date,hardware,location,group,rtype,value 2021-03-01,desk,NY,opera,type-s,0 2021-03-01,desk,NJ,opera,type-s,200 2021-03-01,desk,IL,opera,type-s,100 2022-08-01,desk,NY,opera,type-s,275 2021-08-25,desk,IL,opera,type-s,100 2022-09-16,desk,IL,opera,type-s,30 2022-09-16,desk,NY,opera,type-s,0 2022-11-01,desk,NJ,opera,type-s,0 2022-11-01,desk,IL,opera,type-s,0 """ # 读取数据并解析date列 df = pd.read_csv(StringIO(data), parse_dates=['date']) # 定义分组处理函数:移除分组内连续重复的value def remove_consecutive_duplicates(group): # 分组内按date排序 sorted_group = group.sort_values('date') # 筛选与前一行value不同的行,shift()默认下移一行,第一行shift后为NaN,会被保留 mask = sorted_group['value'] != sorted_group['value'].shift() return sorted_group[mask] # 分组处理,group_keys=False避免保留分组键作为索引 result_df = df.groupby(['hardware', 'location', 'group', 'rtype'], group_keys=False).apply(remove_consecutive_duplicates) # 按date全局排序并重置索引 result_df = result_df.sort_values('date').reset_index(drop=True) # 验证结果 expected_data = """ date,hardware,location,group,rtype,value 2021-03-01,desk,NY,opera,type-s,0 2021-03-01,desk,NJ,opera,type-s,200 2021-03-01,desk,IL,opera,type-s,100 2022-08-01,desk,NY,opera,type-s,275 2022-09-16,desk,IL,opera,type-s,30 2022-09-16,desk,NY,opera,type-s,0 2022-11-01,desk,NJ,opera,type-s,0 2022-11-01,desk,IL,opera,type-s,0 """ expected_df = pd.read_csv(StringIO(expected_data), parse_dates=['date']) print("结果与预期是否一致:", result_df.equals(expected_df)) # 输出True
代码说明
groupby指定分组列,确保仅在同一硬件、地点、组别、类型内处理重复值remove_consecutive_duplicates函数负责分组内的排序和去重:- 先按
date排序保证时间顺序 - 用
shift()比较当前行与前一行的value,筛选出不同的行
- 先按
- 最后全局按
date排序,保证结果的时间顺序
内容的提问来源于stack exchange,提问作者Wajahat
相关产品推荐
相关产品推荐

