pandas如何实现status为1时更新同分组前两日的状态值
需求说明
现有存储多日期下id标识、状态值的DataFrame,需实现如下计算逻辑:
- 按
id1、id2字段对数据分组 - 若某分组下存在某日期的
status值为1,则将该分组内、该日期往前2天范围内的所有记录的状态也更新为1 - 基于原始
status列计算生成新列status_new,不覆盖原始字段值
测试数据
可通过如下代码复现测试数据集:
import pandas as pd data = pd.DataFrame( data=[["xxx",7,"7-1-2022",0],["xxx",4,"7-1-2022",1],["xxx",7,"8-1-2022",0],["xxx",7,"9-1-2022",1],["yyy",4,"10-1-2022",0],["yyy",7,"10-1-2022",0]], columns=["id1","id2","date","status"] )
数据样例参考:
原有错误实现
之前尝试的代码运行结果不符合预期,代码如下:
df['date']=pd.to_datetime(df['date']).dt.date grouped=df.groupby([id1,id2])['date'] df['status']= grouped.shift().dt.date.where(grouped.diff().dt.days<3,df['status'])
该实现的问题在于仅通过相邻行的日期差判断,没有匹配所有status=1的日期向前回溯2天的窗口,且直接覆盖了原始status列。
正确实现方案
实现步骤:
- 先将
date列转换为datetime类型,方便做日期差值计算 - 按
id1、id2分组遍历,对每个分组先提取所有status=1的触发日期 - 对分组内每条记录,判断其日期是否落在任意触发日期的前2天窗口内,是则
status_new为1,否则保留原始status值
完整可运行代码:
import pandas as pd # 读取/构造原始数据 df = pd.DataFrame( data=[["xxx",7,"7-1-2022",0],["xxx",4,"7-1-2022",1],["xxx",7,"8-1-2022",0],["xxx",7,"9-1-2022",1],["yyy",4,"10-1-2022",0],["yyy",7,"10-1-2022",0]], columns=["id1","id2","date","status"] ) # 转换日期格式 df["date"] = pd.to_datetime(df["date"]) def update_group_status(group_df): # 提取当前分组内所有状态为1的触发日期 trigger_dates = group_df.loc[group_df["status"] == 1, "date"].to_list() def get_new_status(row): # 原始状态为1直接返回1 if row["status"] == 1: return 1 # 判断是否在任意触发日期的前2天窗口内 for trigger_date in trigger_dates: day_diff = (trigger_date - row["date"]).days if 0 <= day_diff <= 2: return 1 return 0 group_df["status_new"] = group_df.apply(get_new_status, axis=1) return group_df # 分组应用计算逻辑 df = df.groupby(["id1", "id2"], group_keys=False).apply(update_group_status) # 如需将日期转回原字符串格式可执行如下代码 df["date"] = df["date"].dt.strftime("%-m-%-d-%Y")
运行后结果符合预期:id1=xxx、id2=7分组下,9-1-2022的status为1,其前2天的8-1-2022、7-1-2022对应记录的status_new都会被更新为1,其余不满足窗口条件的记录保持原始状态值。
内容的提问来源于stack exchange,提问作者Sangeetha R
相关产品推荐
相关产品推荐

