如何在Pandas中基于数值与多列按产品执行计算?
问题描述
需要为DataFrame添加一个计算列,计算逻辑按产品维度独立执行,规则如下:
- 默认使用
quantity列的值 - 当
promo[Y/N] = 1时,取上周的计算值乘以(1 + Season/100) - 若为该产品的第一周且
promo[Y/N] = 1,仍保留quantity列的值
示例数据(带计算逻辑注释)
week product promo[Y/N] quantity Season calculation 1 A 0 100 6 100 # no promo, so = quantity col 2 A 0 100 10 100 # no promo, so = quantity col 3 A 1 ? -10 90 # 100 (quantity last week)- 10% (season) 4 A 1 ? 20 108 # quantity last week, what we calculated, 90 + 20% (18) = 108. 5 A 0 80 4 80 # no promo, so = quantity col 1 B 1 100 6 100 # Promo, but first week of this product. So regular quantity. 2 B 0 100 10 100 # no promo, so = quantity col 3 B 1 ? -10 90 # 100 (quantity last week)- 10% (season) 4 B 1 ? 20 108 # quantity last week, what we calculated, 90 + 20% (18) = 108. 5 B 0 80 4 80 # no promo, so = quantity col
尝试过的方法及问题
- 使用
groupby()按Product分组:会打乱原DataFrame的格式,无法保留原有行顺序和结构 - 使用
iterrows()遍历DataFrame:无法区分不同产品,导致计算逻辑错误
解决方案
可以通过groupby('product')分组后,对每个分组应用自定义函数计算,既保证分组逻辑正确,又能保留原数据结构。具体代码如下:
import pandas as pd # 构造示例数据 data = { 'week': [1,2,3,4,5,1,2,3,4,5], 'product': ['A','A','A','A','A','B','B','B','B','B'], 'promo[Y/N]': [0,0,1,1,0,1,0,1,1,0], 'quantity': [100,100,None,None,80,100,100,None,None,80], 'Season': [6,10,-10,20,4,6,10,-10,20,4] } df = pd.DataFrame(data) # 定义每个产品分组的计算函数 def calculate_group(group): # 按周排序确保计算顺序正确 group = group.sort_values('week').reset_index(drop=True) calc = [] for idx, row in group.iterrows(): if idx == 0: # 第一周直接取quantity calc_val = row['quantity'] else: if row['promo[Y/N]'] == 0: # 无promo时取quantity calc_val = row['quantity'] else: # 有promo时用上一周计算值乘季节系数 calc_val = calc[idx-1] * (1 + row['Season']/100) calc.append(calc_val) group['calculation'] = calc return group # 按产品分组计算并合并结果,保留原格式 df = df.groupby('product', group_keys=False).apply(calculate_group) # 输出结果 print(df)
代码说明
- 分组隔离逻辑:通过
groupby('product')拆分数据,确保每个产品的计算独立进行,避免跨产品干扰 - 排序保证时序:每个分组内按
week排序,确保计算严格遵循时间顺序 - 逐行规则计算:遍历分组内每行,根据第一周、promo状态等规则生成计算值
- 保留原数据结构:
group_keys=False参数避免分组键干扰,合并后自动还原原DataFrame的行顺序和格式
运行后得到的calculation列与示例完全一致,且原数据结构不受影响。
内容的提问来源于stack exchange,提问作者R overflow
相关产品推荐
相关产品推荐

