如何基于组间时间差条件创建新列并合并满足时间阈值的分组
如何基于组间时间差合并分组生成新列
嘿,这个需求我之前处理过类似的,咱们一步步来搞定它!核心逻辑很明确:只要当前组和下一组的group_start_time间隔小于5分钟,就把它们归为同一个new_group。咱们用Pandas来实现,步骤非常清晰:
第一步:先处理时间格式
首先得把字符串类型的group_start_time转换成Pandas可计算的时间类型,不然没法算时间差:
import pandas as pd # 先构造你的示例DataFrame data = { 'country': ['UK', 'UK', 'UK', 'UK'], 'fruit': ['apple', 'apple', 'banana', 'apple'], 'time': ['12:20', '12:22', '12:22', '12:26'], 'group': ['a', 'a', 'b', 'c'], 'group_start_time': ['12:20', '12:20', '12:22', '12:26'] } df = pd.DataFrame(data) # 转换时间列,这里假设是当天的时间,有日期的话直接用原日期即可 df['group_start_time'] = pd.to_datetime('2024-01-01 ' + df['group_start_time'])
第二步:按组聚合并计算相邻组的时间差
因为每个组的group_start_time是统一的,所以先按group分组提取每组的起始时间,再计算和下一组的时间差:
# 按group分组,获取每个组的起始时间(取第一个值就行,每组的start_time都一致) group_info = df.groupby('group')['group_start_time'].first().reset_index() # 计算当前组与下一组的时间差,转成分钟单位 group_info['time_diff_to_next'] = group_info['group_start_time'].shift(-1) - group_info['group_start_time'] group_info['time_diff_to_next'] = group_info['time_diff_to_next'].dt.total_seconds() / 60
第三步:生成合并后的new_group标记
接下来给每个组标记归属的合并组:如果当前组和下一组的时间差小于5分钟,就和上一组同属一个new_group;否则新建一个。这里用cumsum累计分组ID,再把每组的第一个组名作为合并组的名称:
# 标记需要新建组的位置:时间差>=5分钟时(最后一组默认归为新组) group_info['new_group_id'] = (group_info['time_diff_to_next'].fillna(5) >= 5).cumsum() # 把每个合并组的第一个组名作为new_group的名称 group_info['new_group'] = group_info.groupby('new_group_id')['group'].transform('first')
第四步:把new_group映射回原DataFrame
最后把分组信息合并回原表格,就得到你想要的结果了:
# 合并回原DataFrame df = df.merge(group_info[['group', 'new_group']], on='group', how='left') # 如果需要把时间列转回字符串格式,执行这一步 df['group_start_time'] = df['group_start_time'].dt.time.astype(str)
运行完代码后,就能得到期望的输出:
country fruit time group group_start_time new_group 0 UK apple 12:20 a 12:20 a 1 UK apple 12:22 a 12:20 a 2 UK banana 12:22 b 12:22 a 3 UK apple 12:26 c 12:26 a
补充说明
- 如果你的数据本身带日期,直接转成datetime即可,不用加固定日期;
- 这个逻辑支持连续合并:比如a和b差2分钟,b和c差4分钟,那a、b、c会被合并成同一个new_group,完全符合你的需求;
- 如果后续有组d的start_time是12:32(和c差6分钟),那d会自动成为一个新的new_group。
内容的提问来源于stack exchange,提问作者asd
相关产品推荐
相关产品推荐

