You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

尝试过的方法及问题

  1. 使用groupby()按Product分组:会打乱原DataFrame的格式,无法保留原有行顺序和结构
  2. 使用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)

代码说明

  1. 分组隔离逻辑:通过groupby('product')拆分数据,确保每个产品的计算独立进行,避免跨产品干扰
  2. 排序保证时序:每个分组内按week排序,确保计算严格遵循时间顺序
  3. 逐行规则计算:遍历分组内每行,根据第一周、promo状态等规则生成计算值
  4. 保留原数据结构:group_keys=False参数避免分组键干扰,合并后自动还原原DataFrame的行顺序和格式

运行后得到的calculation列与示例完全一致,且原数据结构不受影响。


内容的提问来源于stack exchange,提问作者R overflow

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 01:05:18