You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何判断DataFrame中val列值是否按时间顺序连续出现?

识别DataFrame中按时间顺序连续出现的val序列

看起来你想要的是识别val列中按时间顺序不间断连续出现的相同值序列——也就是当某个值被其他值打断后,就算后续再次出现,也会被视为新的连续序列。你的尝试用了日期分组和时长计算,但可能没抓住“连续相同值”这个核心判断点。

下面是一个直接有效的解决方案,我们可以通过标记连续相同值的分组,再对每个分组统计关键信息:

步骤说明

  1. 确保时间列是datetime类型并按时间排序(这是基础,保证序列是时间顺序)。
  2. 生成连续序列分组ID:通过比较当前行的val和上一行的val,如果不同则分组ID递增,这样相同val连续出现的行会被归为同一组。
  3. 按分组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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 07:17:11