You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pandas如何按相邻行类型对应不同时间间隔规则分组生成新列

按规则生成new_group分组列实现方案

分组规则

目标DataFrame已按人员、购买时间完成排序,分组逻辑仅针对product=fruit的记录,other类记录不分配组号,同人员下组号独立从1开始计数:

  • 若当前fruit行的上一行记录product为fruit:两条记录时间间隔≤10分钟则归为同一组,间隔超过10分钟则新建分组
  • 若当前fruit行的上一行记录product为other:当前fruit行与上一个fruit记录时间间隔≤2分钟则归为同一组,间隔超过2分钟则新建分组

示例参考数据

person   time_bought  product    new_group
abby     2:21         fruit        1
abby     2:25         fruit        1  (2.25与2.21间隔在10分钟内,属于同一组)
abby     10:35        fruit        2  
abby     10:40        other
abby     10:42        fruit        2  (10.42与10.35间隔在2分钟内,属于同一组)
abby     10:53        fruit        3  (10.53与10.42间隔超过10分钟,属于新分组)
barry    12:00        fruit        1
...

原有代码问题

  • 时间差计算未跳过other类记录,插入other行后diff计算的是和other行的间隔,而非和上一个fruit行的间隔
  • 未按person维度重置组号计数,跨人员会累计组号导致编号错误
  • 未对非fruit行做空值处理,mask逻辑无法覆盖所有边界场景

正确实现代码

首先确保时间字段为datetime格式,若已完成格式转换可跳过第一步:

import pandas as pd
import numpy as np

# 时间格式转换
df['time_bought'] = pd.to_datetime(df['time_bought'], format='%H:%M')

核心分组逻辑:

# 标记fruit类记录
fruit_mask = df['product'] == 'fruit'

# 按人员分组,取当前行之前最近一个fruit记录的购买时间
df['last_fruit_time'] = df.groupby('person')['time_bought'].transform(
    lambda x: x.where(fruit_mask).ffill().shift(1)
)
# 计算当前fruit行和上一个fruit行的时间差(单位:分钟)
df['time_diff'] = (df['time_bought'] - df['last_fruit_time']).dt.total_seconds() / 60
# 取当前行上一条记录的product类型
df['prev_product'] = df.groupby('person')['product'].shift(1)

# 标记新分组边界
df['new_group_flag'] = np.where(
    ~fruit_mask,
    False, # 非fruit行不参与分组
    np.where(
        df['last_fruit_time'].isna(),
        True, # 每个人员的第一条fruit记录为新组起点
        np.where(
            df['prev_product'] == 'other',
            df['time_diff'] > 2, # 上一条是other,间隔超2分钟则新建组
            df['time_diff'] > 10 # 上一条是fruit,间隔超10分钟则新建组
        )
    )
)

# 按人员累计分组标记生成组号,非fruit行置为空值
df['new_group'] = np.where(
    fruit_mask,
    df.groupby('person')['new_group_flag'].cumsum(),
    np.nan
)

# 可选:删除中间辅助列
df = df.drop(columns=['last_fruit_time', 'time_diff', 'prev_product', 'new_group_flag'])

逻辑说明

  • 先通过ffill对齐每个fruit行对应的上一个fruit行时间,避免other行插入导致时间差计算错误
  • 按人员维度独立计算分组标记,保证不同人员的组号从1开始独立计数
  • 分层判断新分组条件,完全匹配给定的间隔规则
  • 非fruit行不参与组号计数,组号仅在fruit行连续累加

内容的提问来源于stack exchange,提问作者asd

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.31 00:36:25