如何使用Pandas识别连续的时间周期?
合并Pandas中连续时间片段的实现方案
核心思路
要识别并合并连续时间片段,关键是按时间排序后标记连续组,再筛选出包含至少2个片段的组进行合并,孤立片段直接排除。
具体步骤及代码实现
1. 准备示例数据
先构造符合需求的DataFrame(实际使用时替换为你的业务数据):
import pandas as pd data = { 'id': [1,2,3,4,5,6,7], 'cost': [10,15,20,5,12,8,18], 'from': ['2024-01-01 01:00:00', '2024-01-01 01:30:00', '2024-01-01 02:00:00', '2024-01-01 04:00:00', '2024-01-01 05:00:00', '2024-01-01 05:30:00', '2024-01-01 10:30:00'], 'to': ['2024-01-01 01:30:00', '2024-01-01 02:00:00', '2024-01-01 02:30:00', '2024-01-01 04:30:00', '2024-01-01 05:30:00', '2024-01-01 06:00:00', '2024-01-01 11:30:00'] } df = pd.DataFrame(data)
2. 转换时间字段类型
确保from和to是可比较的datetime类型,否则无法判断时间连续性:
df['from'] = pd.to_datetime(df['from']) df['to'] = pd.to_datetime(df['to'])
3. 按起始时间排序
必须保证时间片段按先后顺序排列,否则无法正确识别连续关系:
df = df.sort_values('from').reset_index(drop=True)
4. 标记连续分组
通过对比当前行的from与上一行的to,生成连续标记,再以此创建分组ID:
# 标记当前片段是否与上一个片段连续 df['is_continuous'] = df['from'] == df['to'].shift(1) # 生成分组ID:每遇到不连续的片段,分组ID自动递增 df['group_id'] = (~df['is_continuous']).cumsum()
5. 筛选有效分组(排除孤立片段)
只保留包含至少2个片段的分组(单个片段属于孤立周期,不纳入合并范围):
# 统计每个分组的片段数量 group_sizes = df.groupby('group_id').size() # 筛选出片段数≥2的分组ID valid_group_ids = group_sizes[group_sizes >= 2].index # 过滤出有效分组的数据 df_valid = df[df['group_id'].isin(valid_group_ids)]
6. 合并连续周期
对每个有效分组,提取最早的起始时间、最晚的结束时间,可按需汇总其他业务字段(如总费用、片段数量):
result = df_valid.groupby('group_id').agg( 起始时间=('from', 'min'), 结束时间=('to', 'max'), 总费用=('cost', 'sum'), 片段数量=('id', 'count') ).reset_index(drop=True)
最终结果示例
运行上述代码后,result会输出合并后的连续周期:
| 起始时间 | 结束时间 | 总费用 | 片段数量 |
|---|---|---|---|
| 2024-01-01 01:00:00 | 2024-01-01 02:30:00 | 45 | 3 |
| 2024-01-01 05:00:00 | 2024-01-01 06:00:00 | 20 | 2 |
(注:示例中10:30-11:30是单个片段,被判定为孤立周期,未纳入结果)
内容的提问来源于stack exchange,提问作者Hal
相关产品推荐
相关产品推荐

