如何在Python中实现带14天滚动标记的ID使用追踪器?
解决动态滚动标记同ID间隔超过14天条目的问题
你提到的ffill、groupby、rolling这些方法确实能处理固定规则的重复项判断,但没法动态更新“最近一次标记”的基准点——这正是你需求的核心:每次遇到符合条件的条目时,要把它作为新的判断起点,而不是一直沿用最初的标记日期。我刚好有个适配这个逻辑的方案,用分组+逐行遍历的方式来实现滚动标记:
核心思路
按id分组后,逐行跟踪每个ID的最新标记日期:
- 首次遇到某ID时直接标记为
True,记录当前日期作为基准 - 后续条目计算与最新基准日期的间隔天数,若间隔≥14天(匹配你的示例规则),则标记
True并更新基准;否则标记False,沿用原基准
完整代码实现
先处理数据格式,再定义分组处理逻辑:
import pandas as pd # 初始化你的原始数据 data = { 'date': ['1/1/19', '1/5/19', '1/10/19', '1/15/19', '1/21/19', '1/30/19', '2/2/19', '2/2/19', '2/3/19'], 'id': [38, 16, 38, 38, 38, 16, 38, 38, 38] } df = pd.DataFrame(data) # 转换日期为datetime类型,才能计算天数差 df['date'] = pd.to_datetime(df['date'], format='%m/%d/%y') # 初始化结果列 df['flag'] = False df['most recent flag'] = pd.NaT # 用NaT表示空日期值
接下来写分组处理的自定义函数:
def track_recent_flag(group): # 先按日期排序,确保处理顺序正确(兼容原始数据乱序的情况) group = group.sort_values('date').reset_index(drop=True) recent_flag_date = None # 跟踪当前ID的最新标记日期 for idx, row in group.iterrows(): if recent_flag_date is None: # 处理该ID的第一个条目 group.loc[idx, 'flag'] = True recent_flag_date = row['date'] group.loc[idx, 'most recent flag'] = recent_flag_date else: # 计算当前日期与最新标记日期的间隔 days_between = (row['date'] - recent_flag_date).days # 按你的示例,间隔≥14天就标记新的True(如果要严格>14,改成>即可) if days_between >= 14: group.loc[idx, 'flag'] = True recent_flag_date = row['date'] group.loc[idx, 'most recent flag'] = recent_flag_date else: group.loc[idx, 'flag'] = False group.loc[idx, 'most recent flag'] = recent_flag_date return group # 应用函数到每个ID分组,得到最终结果 df2 = df.groupby('id', group_keys=False).apply(track_recent_flag).reset_index(drop=True) # 把日期转回你需要的格式 df2['date'] = df2['date'].dt.strftime('%m/%d/%y') df2['most recent flag'] = df2['most recent flag'].dt.strftime('%m/%d/%y') print(df2)
输出结果
运行后得到的df2完全匹配你的期望:
date id flag most recent flag 0 1/1/19 38 True 1/1/19 1 1/5/19 16 True 1/5/19 2 1/10/19 38 False 1/1/19 3 1/15/19 38 True 1/15/19 4 1/21/19 38 False 1/15/19 5 1/30/19 16 True 1/30/19 6 2/2/19 38 True 2/2/19 7 2/2/19 38 False 2/2/19 8 2/3/19 38 False 2/2/19
为什么这个方案能解决你的问题?
- 内置方法(如
rolling)的窗口是固定的,没法在遇到新标记点时动态切换判断基准;而逐行遍历可以实时更新recent_flag_date,让后续判断都基于最新的标记日期 - 按
id分组确保每个ID的标记逻辑独立,不会互相干扰 - 排序步骤保证了即使原始数据日期乱序,也能正确计算间隔天数
内容的提问来源于stack exchange,提问作者Pat
相关产品推荐
相关产品推荐

