如何判断DataFrame中val列值是否按时间顺序连续出现?
识别DataFrame中按时间顺序连续出现的val序列
看起来你想要的是识别val列中按时间顺序不间断连续出现的相同值序列——也就是当某个值被其他值打断后,就算后续再次出现,也会被视为新的连续序列。你的尝试用了日期分组和时长计算,但可能没抓住“连续相同值”这个核心判断点。
下面是一个直接有效的解决方案,我们可以通过标记连续相同值的分组,再对每个分组统计关键信息:
步骤说明
- 确保时间列是
datetime类型并按时间排序(这是基础,保证序列是时间顺序)。 - 生成连续序列分组ID:通过比较当前行的
val和上一行的val,如果不同则分组ID递增,这样相同val连续出现的行会被归为同一组。 - 按分组ID聚合,统计每个连续序列的开始时间、结束时间、持续时长、出现次数等信息。
完整代码
import pandas as pd # 定义处理函数 def identify_consecutive_val(df): # 转换时间列为datetime并按时间排序 df = df.copy() df['time_1'] = pd.to_datetime(df['time_1']) df = df.sort_values('time_1').reset_index(drop=True) # 生成连续序列的分组ID:当val与前一行不同时,分组ID+1 df['consecutive_group'] = df['val'].ne(df['val'].shift()).cumsum() # 按分组和val聚合,计算关键信息 result = df.groupby(['consecutive_group', 'val'], as_index=False).agg( start_time=('time_1', 'first'), end_time=('time_1', 'last'), duration_hours=('time_1', lambda x: (x.max() - x.min()).total_seconds()/3600), occurrence_count=('time_1', 'count') ) # 可选:添加是否跨日期的标记 result['crosses_date'] = result['start_time'].dt.date != result['end_time'].dt.date return result # 测试df_1 df_1 = pd.DataFrame({ 'subject_id':[1]*11, 'time_1' :['2173-04-03 10:00:00','2173-04-03 10:15:00','2173-04-03 10:30:00','2173-04-03 10:45:00','2173-04-03 11:01:00','2173-04-04 12:00:00','2173-04-05 16:00:00','2173-04-05 22:00:00','2173-04-06 04:00:00','2173-04-06 04:30:00','2173-04-06 06:30:00'], 'val' :[5,5,5,5,5,10,5,8,3,8,10] }) print("df_1的连续序列结果:") print(identify_consecutive_val(df_1)) # 测试df_2 df_2 = pd.DataFrame({ 'subject_id':[1]*11, 'time_1' :['2173-04-03 10:00:00','2173-04-03 10:15:00','2173-04-03 10:30:00','2173-04-03 10:45:00','2173-04-03 11:01:00','2173-04-04 12:00:00','2173-04-05 16:00:00','2173-04-05 22:00:00','2173-04-06 04:00:00','2173-04-06 04:30:00','2173-04-06 06:30:00'], 'val' :[5,6,5,6,5,10,5,8,3,8,10] }) print("\ndf_2的连续序列结果:") print(identify_consecutive_val(df_2))
结果解释
- df_1的结果:前5个5会被归为一个连续组,后续的10、5、8、3、8、10各自成为独立的连续组(因为每个值都被下一个不同的值打断)。
- df_2的结果:你会看到5、6、5、6、5被分成了5个独立的连续组(每个值只出现一次,且被下一个不同值打断),后续的10、5、8、3、8、10同样是独立组,完美符合你对“序列被打断”的判断需求。
这个方案的核心是用ne()(不等于)和cumsum()生成连续分组,这是处理连续相同值序列的经典方法,比按日期分组更直接,因为连续序列可能跨日期,也可能在同一天内被打断。
内容的提问来源于stack exchange,提问作者The Great
相关产品推荐
相关产品推荐

