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

基于分组与时间约束的奶牛跛行Life_xLame计数异常问题

问题排查与修正方案

问题根源

单泌乳期的NID(如52316、35724)所有跛行记录归属同一泌乳期,原有Life_xLame计算逻辑基于全局NID的跛行时间序列做间隔判断,而非针对每个RxDate单独筛选早于该日期的跛行记录后再统计。这导致同一NID的多个RxDate复用全局间隔计算结果,无法重置计数;而多泌乳期NID因泌乳期分割,每个RxDate对应的跛行记录子集独立,计数逻辑自然生效。

修正方案

针对每个(NID, RxDate)组合,独立筛选早于该日期的跛行记录,从头统计间隔超7天的病例数,确保每个RxDate的计数独立计算。

代码实现

import pandas as pd

# 确保日期字段为datetime类型
df['RxDate'] = pd.to_datetime(df['RxDate'])
df['LameDate'] = pd.to_datetime(df['LameDate'])

# 定义函数:针对单个(NID, RxDate)组,计算符合条件的跛行病例数
def calculate_life_lame(group):
    current_rx = group['RxDate'].iloc[0]
    # 筛选早于当前RxDate的跛行记录,按时间排序
    valid_lames = group[group['LameDate'] < current_rx].sort_values('LameDate')
    
    if valid_lames.empty:
        return 0
    
    # 统计间隔>7天的病例数(第一个病例默认计入)
    count = 1
    last_lame_date = valid_lames['LameDate'].iloc[0]
    
    for date in valid_lames['LameDate'].iloc[1:]:
        if (date - last_lame_date).days > 7:
            count += 1
            last_lame_date = date
    
    return count

# 计算Life_xLame:按NID+RxDate分组应用函数
df['Life_xLame'] = df.groupby(['NID', 'RxDate']).apply(calculate_life_lame).reset_index(level=[0,1], drop=True)

# 保留原正确的Lact_xLame计算逻辑
df['Lact_Lag'] = df.groupby(['NID', 'Lactation'])['LameDate'].diff().dt.days
df['Lact_xLame'] = df.groupby(['NID', 'Lactation', 'RxDate']).apply(
    lambda x: (x['Lact_Lag'].isna() | (x['Lact_Lag'] > 7)).cumsum().max()
).reset_index(level=[0,1,2], drop=True)

特殊场景适配(如需重置计数)

若需求是每个RxDate仅统计上一个RxDate之后到当前RxDate之间的符合条件病例数,可使用以下函数实现计数重置:

def calculate_life_lame_reset(group):
    # 对当前NID的RxDate按时间排序
    sorted_group = group.sort_values('RxDate').reset_index(drop=True)
    counts = []
    last_rx = None
    last_valid_lame = None
    
    for idx, row in sorted_group.iterrows():
        current_rx = row['RxDate']
        # 筛选时间范围:上一个RxDate之后,当前RxDate之前
        if last_rx:
            valid_lames = group[(group['LameDate'] > last_rx) & (group['LameDate'] < current_rx)].sort_values('LameDate')
        else:
            valid_lames = group[group['LameDate'] < current_rx].sort_values('LameDate')
        
        # 统计间隔>7天的病例数
        cnt = 0
        temp_last = last_valid_lame
        for date in valid_lames['LameDate']:
            if temp_last is None or (date - temp_last).days > 7:
                cnt += 1
                temp_last = date
        
        counts.append(cnt)
        last_rx = current_rx
        last_valid_lame = temp_last
    
    sorted_group['Life_xLame'] = counts
    return sorted_group

# 应用重置逻辑
df = df.groupby('NID').apply(calculate_life_lame_reset).reset_index(drop=True)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 07:07:16