You need to enable JavaScript to run this app. Pandas 基于条件列与分组计算顺序行日期间隔
优惠活动
大模型
产品
解决方案
定价
更多

Pandas 基于条件列与分组计算顺序行日期间隔

原有代码报错原因
  • apply调用逻辑错误:pandas的apply方法要求传入可调用的函数对象,原代码中df.apply(func(df['offer_req_type'], df['or_date']))的写法是立即执行func函数,将函数的返回结果作为参数传给apply,pandas无法识别这个无名称的返回对象作为合法的可调用函数,因此抛出SpecificationError。
  • 业务逻辑缺失:即便修正调用方式,原代码没有按公寓编号拆分计算范围,全局循环时会跨公寓累计报价日期,把不同公寓的报价、请求数据混算;同时函数中对报价行返回-1的处理,和样例中报价行间隔为0的规则不匹配,结果不符合预期。
适配业务需求的groupby实现方案

相比逐行循环的自定义函数,向量化的ffill(向前填充)方案效率更高,逻辑也完全匹配业务规则,步骤如下:

  1. 首先将文本格式的日期列转为pandas datetime类型:
    import pandas as pd
    # 转换日期格式
    df['or_date'] = pd.to_datetime(df['or_date'])
    
  2. 构造临时列,仅保留所有报价行的日期,请求行的临时值为空:
    df['recent_offer_date'] = df.loc[df['offer_req_type'] == 'offer', 'or_date']
    
  3. 按公寓编号分组,在每个公寓的已排序数据中,将最近一次报价的日期向前填充到后续所有行,直到遇到下一次报价才更新值:
    df['recent_offer_date'] = df.groupby('apartment')['recent_offer_date'].ffill()
    
  4. 计算日期差,生成目标列:
    # 报价行自身的差值为0,首次报价前的请求行因无匹配报价日期自动得到空值,对应样例中的n/a
    df['days_since_offer'] = (df['or_date'] - df['recent_offer_date']).dt.days
    
过往方案不符合预期的原因
  • 之前使用df.groupby('offer_req_type').or_date.diff().dt.days的逻辑是按请求、报价类型分组计算相邻行差值,和业务要求的「按公寓追踪最近报价位置」完全不匹配,因此结果必然错误。
  • 单纯用shift方法无法适配的核心原因是:shift是固定偏移固定行数,遇到连续多笔请求时,只能拿到上一行的日期,无法跳过中间的请求行、定位到真正的上一次报价日期;配合ffill的向前填充逻辑,就能跳过连续请求行,一直沿用最近的报价日期,直到遇到新的报价再更新。
自定义函数的适配写法

如果需要沿用原有自定义函数的逻辑,需要将其改造为适配groupby apply的形式,按每个公寓组单独计算,参考写法:

def calc_group_lapse(group):
    offer_dt = None
    lapse_list = []
    for _, row in group.iterrows():
        if row['offer_req_type'] == 'offer':
            offer_dt = row['or_date']
            lapse_list.append(0)
        else:
            # 首次报价前的请求行标记为空,对应n/a
            lapse_list.append((row['or_date'] - offer_dt).days if offer_dt else None)
    group['days_since_offer'] = lapse_list
    return group
# 按公寓分组应用计算,关闭group_keys避免多余层级
df = df.groupby('apartment', group_keys=False).apply(calc_group_lapse)

这个写法的计算结果和向量化ffill方案一致,但数据量大时循环效率会显著低于向量化操作。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.05 03:45:04