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

使用groupby后如何计算各年龄组产品销量的同比增长率?

问题描述

我有如下示例数据:

pd.DataFrame({'date': {0: Timestamp('2021-08-01 00:00:00'),
  1: Timestamp('2022-08-01 00:00:00'),
  2: Timestamp('2021-08-01 00:00:00'),
  3: Timestamp('2021-08-01 00:00:00'),
  4: Timestamp('2022-08-01 00:00:00'),
  5: Timestamp('2022-08-01 00:00:00')},
 'customer_nr': {0: 2, 1: 3, 2: 2, 3: 3, 4: 2, 5: 2},
 'product_nr': {0: 3, 1: 2, 2: 2, 3: 1, 4: 2, 5: 1},
 'age': {0: 32.0, 1: 32.0, 2: 32.0, 3: 32.0, 4: 32.0, 5: 37.0},
 'gender': {0: 'M', 1: 'M', 2: 'M', 3: 'M', 4: 'M', 5: 'M'},
 'age_group': {0: '25-34',
  1: '25-34',
  2: '25-34',
  3: '25-34',
  4: '25-34',
  5: '35-44'}} )

执行分组操作:

df.groupby(['date','product_nr','age_group']).age.count().unstack()

得到结果:

dateproduct_nr25-3435-44
2021-08-0111NaN
21NaN
31NaN
2022-08-011NaN1
22NaN

现在需要计算从第一个日期到第二个日期,各年龄组下产品销量的增长百分比,期望得到如下格式的结果:

product_nr25-3435-4445-5455-64
1x%x%x%x%
2x%x%x%x%
3x%x%x%x%

注:原始数据集包含更多产品和客户,且两年的product_nr数量和排序不一致。

解决方案

通过以下步骤可实现需求:

  1. 重塑分组结果结构:将多层索引数据转换为宽表,让日期成为独立列,便于计算增长。
  2. 填充缺失值:用0填充NaN,避免因两年产品/年龄组不匹配导致的计算错误。
  3. 计算增长百分比:按公式(后期销量-前期销量)/前期销量*100计算增长率,同时处理前期销量为0的特殊情况(如新增产品)。
  4. 整理目标格式:调整结果为以product_nr为索引、各年龄组为列的结构。

具体代码如下:

# 执行分组操作并保存结果
grouped = df.groupby(['date','product_nr','age_group']).age.count().unstack(fill_value=0)

# 转换多层索引为列,方便后续处理
grouped_flat = grouped.reset_index()

# 提取两个日期(假设日期为升序排列)
date1, date2 = grouped_flat['date'].unique()

# 分别筛选两年数据,设置product_nr为索引
df_year1 = grouped_flat[grouped_flat['date'] == date1].set_index('product_nr').drop('date', axis=1)
df_year2 = grouped_flat[grouped_flat['date'] == date2].set_index('product_nr').drop('date', axis=1)

# 对齐两年的产品和年龄组,缺失值用0填充
df_aligned = df_year2.join(df_year1, how='outer', lsuffix='_y2', rsuffix='_y1').fillna(0)

# 计算增长百分比,处理除数为0的情况
for col in df_year1.columns:
    df_aligned[col] = df_aligned.apply(
        lambda row: ((row[f'{col}_y2'] - row[f'{col}_y1'])/row[f'{col}_y1'])*100 if row[f'{col}_y1'] !=0 else 100,
        axis=1
    )

# 整理成目标格式
result = df_aligned[[col for col in df_year1.columns]].reset_index()

# 可选:将数值格式化为百分比显示
result = result.style.format({col: '{:.2f}%' for col in result.columns if col != 'product_nr'})

执行后即可得到符合要求的结果,原始数据中的其他年龄组会自动被识别处理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 19:27:16