如何从不同Pandas DataFrame计算零售商-SKU跨周销售占比及均值
计算指定周区间内零售商-SKU的销售占比及均值
看起来你已经搞定了前期的数据分组和跨周总和计算,接下来咱们一步步解决销售占比和均值的问题。我用Python pandas(数据分析领域常用工具)来演示具体实现,假设你的数据存在df这个DataFrame里,结构大概是这样:
| retailer | sku | week | sales |
|---|---|---|---|
| A | SKU1 | 201636 | 100 |
| A | SKU2 | 201636 | 200 |
| B | SKU1 | 201636 | 150 |
| ... | ... | ... | ... |
第一步:先把目标周区间的数据筛选出来
你已经定义了score_period这个周区间列表,咱们先把所有符合条件的周数提取出来,再过滤数据:
# 把所有需要的周数整理成一个列表(处理跨年周的情况,比如201652之后是201701) target_weeks = [] for period in score_period: start_week, end_week = period current_week = start_week while current_week <= end_week: target_weeks.append(current_week) # 处理跨年逻辑:如果是当年第52周,下一周是下一年第1周 if current_week % 100 == 52: current_week = (current_week // 100 + 1) * 100 + 1 else: current_week += 1 # 筛选出目标周的数据 filtered_df = df[df['week'].isin(target_weeks)]
第二步:计算销售占比
销售占比通常有两种业务口径,你按需选就行:
口径1:该SKU在对应零售商当周总销售额中的占比
先按零售商+周分组,算出每个零售商每周的总销售额,再合并回原数据计算占比:
# 计算每个零售商每周的总销售额 retailer_weekly_total = filtered_df.groupby(['retailer', 'week'])['sales'].sum().reset_index(name='retailer_weekly_sales') # 把总销售额合并到原数据里 merged_df = pd.merge(filtered_df, retailer_weekly_total, on=['retailer', 'week'], how='left') # 计算占比:SKU销售额 / 对应零售商当周总销售额 merged_df['sku_retailer_share'] = merged_df['sales'] / merged_df['retailer_weekly_sales']
口径2:该零售商-SKU在全市场当周总销售额中的占比
类似的,先算全市场每周的总销售额,再合并计算占比:
# 计算全市场每周的总销售额 market_weekly_total = filtered_df.groupby('week')['sales'].sum().reset_index(name='market_weekly_sales') # 合并数据 merged_df = pd.merge(filtered_df, market_weekly_total, on='week', how='left') # 计算占比:零售商-SKU销售额 / 全市场当周总销售额 merged_df['sku_market_share'] = merged_df['sales'] / merged_df['market_weekly_sales']
第三步:计算目标周内的零售商-SKU均值
这里的均值可以是销售额均值或者占比均值,看你需求:
情况1:每个零售商-SKU在目标周内的销售额均值
# 按零售商+SKU分组,计算销售额的周均值 sku_retailer_avg_sales = merged_df.groupby(['retailer', 'sku'])['sales'].mean().reset_index(name='avg_weekly_sales')
情况2:每个零售商-SKU在目标周内的占比均值(比如用口径1的占比)
# 按零售商+SKU分组,计算占比的周均值 sku_retailer_avg_share = merged_df.groupby(['retailer', 'sku'])['sku_retailer_share'].mean().reset_index(name='avg_sku_retailer_share')
额外:如果需要分区间单独计算
因为你的score_period是多个不连续的周区间,要是想分别计算每个区间内的占比和均值,可以把逻辑封装成函数,遍历每个区间处理:
def compute_period_metrics(df, start_week, end_week): # 生成当前区间的所有周数 period_weeks = [] current = start_week while current <= end_week: period_weeks.append(current) if current % 100 == 52: current = (current // 100 + 1) * 100 + 1 else: current += 1 # 筛选当前区间的数据 period_df = df[df['week'].isin(period_weeks)] # 计算零售商周总销售额&占比(这里用口径1,你可以换成口径2) retailer_weekly_total = period_df.groupby(['retailer', 'week'])['sales'].sum().reset_index(name='retailer_weekly_sales') period_df = pd.merge(period_df, retailer_weekly_total, on=['retailer', 'week'], how='left') period_df['sku_retailer_share'] = period_df['sales'] / period_df['retailer_weekly_sales'] # 计算当前区间内的均值 period_metrics = period_df.groupby(['retailer', 'sku']).agg( avg_sales=('sales', 'mean'), avg_share=('sku_retailer_share', 'mean') ).reset_index() # 加上区间标识,方便区分 period_metrics['period'] = f"{start_week}-{end_week}" return period_metrics # 遍历所有区间,合并结果 all_period_results = pd.concat([compute_period_metrics(df, s, e) for s, e in score_period], ignore_index=True)
这样就能得到每个周区间内,每个零售商-SKU的销售占比和对应的均值啦。
内容的提问来源于stack exchange,提问作者user6083088
相关产品推荐
相关产品推荐

