Pandas:多分组下基于时间范围统计连续周期数的实现问题
解决方法
核心逻辑
按A、B、C分组后,每组内按StartTime排序,周期的数量等于分组内「相邻Block不满足时间间隔≤1天的断裂次数」加1。单个Block的分组断裂次数为0,因此周期数为1,正好符合需求。
代码实现
# 1. 先排序,避免修改原DataFrame df_sorted = df.sort_values(by=['A', 'B', 'C', 'StartTime']).copy() # 2. 分组计算下一行的StartTime与当前行EndTime的间隔天数 df_sorted['next_start'] = df_sorted.groupby(['A', 'B', 'C'])['StartTime'].shift(-1) df_sorted['days_gap'] = (df_sorted['next_start'] - df_sorted['EndTime']).dt.days # 3. 标记断裂点:间隔超过1天,或是分组的最后一行(无下一行) df_sorted['is_break'] = (df_sorted['days_gap'] > 1) | df_sorted['next_start'].isna() # 4. 统计每组的断裂点数量,即为周期数 cycle_count = df_sorted.groupby(['A', 'B', 'C'])['is_break'].sum().reset_index(name='CountCycles')
原代码的问题说明
- 判断条件
df['EndTime'] != df['StartTime'].shift(-1) + pd.Timedelta(days=1)逻辑有误,应该直接计算间隔天数是否≤1,而非用等式匹配。 - 通过筛选mask后统计
Blocks的唯一值,天然会丢失只有单个Block的分组——这类分组没有符合mask的行,根本不会出现在filter_df里。而统计断裂点的方式会覆盖所有分组,包括单个Block的情况。
内容的提问来源于stack exchange,提问作者Thoth0Amon
相关产品推荐
相关产品推荐

