如何为DataFrame添加列统计特定门店产品的连续促销周数?
实现思路与代码示例
要统计特定store_code、product_code下同一promotion_type的连续生效周数,可按以下步骤实现:
核心步骤
- 日期预处理:将
date列转换为日期类型,提取年-周标识(避免跨年周数混淆)。 - 分组排序:按
store_code、product_code、promotion_type分组,确保每组内数据按时间顺序排列。 - 连续组标识:在每个分组内,判断当前周与前一周是否连续(间隔7天),生成连续组的唯一标识。
- 生成连续序号:对每个连续组内的记录,生成从1开始的递增序号,即为
Desired Outcome。
代码实现
import pandas as pd # 示例DataFrame(替换为你的实际数据即可) data = [ [1, 222, "2021-01-03", "Promo descuento", 1], [1, 222, "2021-02-28", "Promo cabecera", 1], [1, 232, "2021-03-21", "Promo multicompra", 1], [1, 296, "2021-01-17", "Promo descuento", 1], [1, 296, "2021-01-24", "Promo descuento", 2], [1, 296, "2021-01-31", "Promo descuento", 3], [1, 296, "2021-02-07", "Promo descuento", 4], [1, 382, "2021-02-07", "Promo descuento", 1], [1, 608, "2021-01-10", "Promo descuento", 1], [1, 608, "2021-01-17", "Promo descuento", 2], [1, 612, "2021-01-03", "Promo descuento", 1], [1, 612, "2021-01-31", "Promo descuento", 1] ] df = pd.DataFrame(data, columns=["store_code", "product_code", "date", "promotion_type", "Desired Outcome_expected"]) # 1. 转换日期格式并提取ISO标准年-周(格式:YYYY-WW) df['date'] = pd.to_datetime(df['date']) df['year_week'] = df['date'].dt.isocalendar().apply(lambda x: f"{x.year}-{x.week:02d}", axis=1) # 2. 按指定字段排序,保证时间顺序正确 df = df.sort_values(by=["store_code", "product_code", "promotion_type", "date"]) # 3. 生成连续组标识:判断当前周与前一周是否间隔7天 def get_continuous_groups(week_series): # 将年-周转换为该周周一的日期,方便计算间隔 week_dates = pd.to_datetime(week_series + "-1", format="%G-%V-%u") # 与前一周天数差不等于7时,标记为新组 new_group = (week_dates - week_dates.shift()).dt.days != 7 # 累计新组标识,得到连续组ID return new_group.cumsum() df['group_id'] = df.groupby(["store_code", "product_code", "promotion_type"])['year_week'].apply(get_continuous_groups) # 4. 生成连续生效周数 df['Desired Outcome'] = df.groupby(["store_code", "product_code", "promotion_type", "group_id"]).cumcount() + 1 # 查看结果(可对比预期值验证) print(df[["store_code", "product_code", "date", "promotion_type", "Desired Outcome_expected", "Desired Outcome"]])
关键说明
- 使用ISO年-周(
dt.isocalendar())是为了避免跨年时周数混乱,比如2020年第52周和2021年第1周不会被误判为连续。 - 连续周的判断基于间隔7天,如果业务中对“连续周”的起始日定义不同(比如以周日为一周第一天),可将
%u改为%w调整日期转换格式。 - 最终生成的
Desired Outcome完全匹配示例需求:比如product_code=612的两条记录因周数不连续,结果均为1;product_code=296的四条连续周记录则生成1-4的序列。
内容的提问来源于stack exchange,提问作者diana
相关产品推荐
相关产品推荐

