如何在Pandas中基于行条件生成前3周销售额求和的新列?
解决Pandas中按实际周数计算前3周销售额之和的问题
刚好遇到过类似的场景,shift()确实在周数不连续的时候不好用,你的思路完全正确——直接根据每行的周数,去匹配它的前3周(w-1、w-2、w-3)的销售额求和就对了!
先给你修正一下示例数据(原数据里Sales和Week的长度不一致,我调整成每行对应的数据),然后一步步实现:
步骤1:准备正确的示例数据
import pandas as pd df = pd.DataFrame({ "A": ['a','a','a','a','a','a','b','b','b','b'], "Sales": [2,3,7,1,4,3,5,6,9,10], "Week": [1,2,3,4,5,11,1,2,3,4] })
步骤2:实现核心逻辑(高效版)
如果数据量较大,每次分组筛选会比较慢,我们可以先为每个A分组建立周数-销售额的字典映射,这样查找起来更快:
# 为每个A分组创建周数到销售额的映射字典 week_sales_maps = df.groupby('A').apply(lambda g: dict(zip(g['Week'], g['Sales']))).to_dict() # 定义函数计算当前行的前3周销售额之和 def get_last3_week_sum(row): # 获取当前分组的周-销售额映射 sales_dict = week_sales_maps[row['A']] # 对w-1、w-2、w-3的销售额求和,不存在的周数默认取0 return sum(sales_dict.get(week, 0) for week in [row['Week']-1, row['Week']-2, row['Week']-3]) # 生成新列 df['Last3WeekSales'] = df.apply(get_last3_week_sum, axis=1)
步骤3:查看结果
运行后输出的结果和你期望的完全一致:
A Sales Week Last3WeekSales 0 a 2 1 0 1 a 3 2 2 2 a 7 3 5 3 a 1 4 12 4 a 4 5 11 5 a 3 11 0 6 b 5 1 0 7 b 6 2 5 8 b 9 3 11 9 b 10 4 20
补充说明
- 为什么不用
shift()?因为shift()是按行的位置偏移,不管实际的周数。比如如果某周的数据缺失,shift(1)会拿到上一行的周(可能是w-2甚至更多),结果就错了。 - 分组处理是关键:每个
A类别(比如a和b)的周数据是独立的,不能跨类别计算前3周的销售额。 - 如果你的数据量很小,也可以用分组筛选的方式(代码更直观,但效率稍低):
def calculate_last3_sales(group, current_week): # 筛选当前周的前3周记录 prev_weeks = group[group['Week'].isin([current_week-1, current_week-2, current_week-3])] return prev_weeks['Sales'].sum() df['Last3WeekSales'] = df.groupby('A').apply( lambda g: g['Week'].apply(lambda w: calculate_last3_sales(g, w)) ).reset_index(level=0, drop=True)
内容的提问来源于stack exchange,提问作者Chetanya Saxena
相关产品推荐
相关产品推荐

