在Pandas中统计连续时间戳内站点的出现次数及起止时间
解决站点连续时段统计问题的Pandas方案
这需求太常见了,用Pandas几步就能搞定,我给你写个完整的实现,连细节都给你考虑到了:
步骤说明
首先得确保时间列是可计算的datetime类型,然后按站点分组,识别连续的小时段,最后聚合统计就行。
完整代码实现
import pandas as pd # 先构造你的示例数据(实际替换成你自己的DataFrame即可) data = { 'Hour': [ '01/08/2020 00:00', '01/08/2020 00:00', '01/08/2020 00:00', '01/08/2020 00:00', '01/08/2020 01:00', '01/08/2020 01:00', '01/08/2020 01:00', '01/08/2020 01:00', '01/08/2020 02:00', '01/08/2020 02:00', '01/08/2020 03:00', '01/08/2020 03:00', '01/08/2020 23:00', '02/08/2020 00:00' ], 'Site': ['A', 'B', 'C', 'D', 'A', 'B', 'E', 'F', 'A', 'E', 'C', 'G', 'G', 'G'] } df = pd.DataFrame(data) # 1. 把Hour列转成datetime类型,这是后续时间计算的核心基础 df['Hour'] = pd.to_datetime(df['Hour'], format='%d/%m/%Y %H:%M') # 2. 按Site分组并排序,确保每个站点的时间是按顺序排列的(避免原数据乱序影响判断) df_sorted = df.sort_values(['Site', 'Hour']).reset_index(drop=True) # 3. 识别连续的小时段:计算相邻时间差,非1小时则标记为新时段,再给每个连续段分配唯一ID df_sorted['time_diff'] = df_sorted.groupby('Site')['Hour'].diff() df_sorted['is_new_period'] = df_sorted['time_diff'] != pd.Timedelta(hours=1) df_sorted['period_id'] = df_sorted.groupby('Site')['is_new_period'].cumsum() # 4. 聚合统计每个站点的每个连续时段 result = df_sorted.groupby(['Site', 'period_id']).agg( count=('Hour', 'nunique'), # 统计连续出现的小时数(若单小时内站点重复,换成count即可) period_start=('Hour', 'min'), period_end=('Hour', 'max') ).reset_index(drop=True) # 可选:把时间转回你需要的字符串格式 result['period_start'] = result['period_start'].dt.strftime('%d/%m/%Y %H:%M') result['period_end'] = result['period_end'].dt.strftime('%d/%m/%Y %H:%M') # 调整列顺序,匹配你需要的输出格式 result = result[['period_start', 'Site', 'count', 'period_end']] print(result)
代码细节解释
- 时间类型转换:必须把字符串转成datetime,不然没法计算时间差和排序;
- 分组排序:确保每个站点的时间是按顺序排列的,避免原数据乱序导致连续判断出错;
- 连续时段识别:用
diff()计算相邻时间差,只要不是1小时就判定为新时段,再用cumsum()给每个连续段分配唯一ID; - 聚合统计:按站点和时段ID分组,统计出现次数(
nunique适用于单小时单站点仅出现一次的场景,若有重复则用count),同时取时段的最早和最晚时间。
输出示例
运行后你会得到类似这样的结果:
period_start Site count period_end 0 01/08/2020 00:00 A 3 01/08/2020 02:00 1 01/08/2020 00:00 B 2 01/08/2020 01:00 2 01/08/2020 00:00 C 1 01/08/2020 00:00 3 01/08/2020 03:00 C 1 01/08/2020 03:00 4 01/08/2020 00:00 D 1 01/08/2020 00:00 5 01/08/2020 01:00 E 2 01/08/2020 02:00 6 01/08/2020 01:00 F 1 01/08/2020 01:00 7 01/08/2020 03:00 G 2 02/08/2020 00:00
完全匹配你要的统计需求,要是你的数据有特殊情况(比如单小时内站点重复),只需要调整聚合时的统计方法就行,灵活得很。
内容的提问来源于stack exchange,提问作者xubaer
相关产品推荐
相关产品推荐

