如何在Pandas DataFrame中提取连续时间戳序列的首尾时间戳
提取Pandas中连续时间戳序列的首尾时间戳
需求说明
现有一个包含timestamp列的Pandas DataFrame,该列时间戳均按分钟取整,且DataFrame已按此列升序排序。需要提取所有长度至少为5的连续时间戳序列(相邻时间戳间隔1分钟)的首尾时间戳。例如示例中2022-10-06 16:25:00到2022-10-06 16:29:00的序列长度为5,符合要求;而16:36:00到16:37:00的序列长度不足5,不纳入结果。
示例数据
import pandas as pd df = pd.DataFrame({'timestamp': ['2022-10-06 16:21:00', '2022-10-06 16:25:00', '2022-10-06 16:26:00', '2022-10-06 16:27:00', '2022-10-06 16:28:00', '2022-10-06 16:29:00', '2022-10-06 16:36:00', '2022-10-06 16:37:00'], 'data': ['bla', 'bla', 'bla', 'bla', 'bla', 'bla', 'bla', 'bla']}) df['timestamp'] = pd.to_datetime(df['timestamp'])
已完成步骤
已计算相邻时间戳的分钟差:
df['delta'] = (df['timestamp'] - df['timestamp'].shift(1)).dt.total_seconds()/60
高效实现方法
步骤1:标记连续序列分组
通过判断delta是否等于1,将不连续的位置标记为新分组的起点,再用cumsum()生成分组ID:
df['group'] = (df['delta'] != 1).cumsum()
注:第一行的delta为NaN,会被判定为不等于1,自动作为第一个分组的起点。
步骤2:筛选长度≥5的分组
按分组ID聚合,统计每个分组的时间戳数量,筛选出符合长度要求的分组:
# 提取有效分组的ID valid_group_ids = df.groupby('group')['timestamp'].count()[lambda x: x >= 5].index
步骤3:提取首尾时间戳
从原DataFrame中筛选出有效分组的数据,再按分组聚合取首尾时间戳,最后转为列表格式:
# 获取结果 result = df[df['group'].isin(valid_group_ids)].groupby('group')['timestamp'].agg(['first', 'last']).values.tolist()
链式优化版本(无需保留中间列)
如果不需要保留delta和group列,可以用链式操作简化流程:
result = (df.assign(group=(df['timestamp'].diff().dt.total_seconds()/60 != 1).cumsum()) .groupby('group') .filter(lambda g: len(g) >= 5) .groupby('group')['timestamp'] .agg(['first', 'last']) .values.tolist())
结果示例
执行后result的输出为:
[[Timestamp('2022-10-06 16:25:00'), Timestamp('2022-10-06 16:29:00')]]
内容的提问来源于stack exchange,提问作者Pedaalemmer
相关产品推荐
相关产品推荐

