十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Python渠道分析实战:从指标口径到自动化PPT

Python渠道分析实战:从指标口径到自动化PPT 简介康师傅方便面渠道分析PPT是一份面向市场营销、渠道管理及快消品行业学习者的案例分析型资源适合用于课程展示、论文参考或企业内部分享。内容系统梳理了康师傅方便面从1992年至今的渠道演进历程涵盖“国营制”“大经销商制”“通路精耕制”和“精准式行销”四个阶段并详细拆解一阶、二阶、三阶渠道以及农贸批发市场自然辐射模式同时针对终端市场控制力不足、价格体系混乱、窜货现象严重等现实问题给出了经销商选择评估与窜货整治等对策。资源打包为1个PPT文件大小约638KB页面结构清晰图表结合便于理解。已有93人学习对把握快消品渠道设计、渠道冲突治理与精细化分销策略具有实用参考价值。1. 康师傅方便面渠道分析先搞清楚问题再去做PPT某次月度经营分析会上销售总监打开一份全是累计销售额表格的PPT董事长问了一句现代渠道这个月掉量到底是门店数量少了还是货架被竞品挤压了会议室安静了十几秒。做快消品渠道分析的朋友应该都有同感报表没少做但问题没被回答。康师傅方便面这类产品渠道结构非常典型——现代渠道里有NKA大卖场、CVS便利店传统渠道里有批发和食杂店电商渠道还有平台电商和O2O即时零售。渠道分析如果只停留在汇总销售额、画张饼图很难定位掉量原因。这篇文章不做理论本直接讲落地路径先定指标口径再清洗多源数据最后用Python把图表和结论自动生成PPT。2. 渠道分析先立指标铺货率、动销率、货架份额怎么算做渠道分析最忌讳直接打开流水表开干。不同部门对铺货率的理解可以差出十几个百分点原因通常只是分母不同。所以我会在分析文件里先放一张指标口径表固定下来再写代码。否则后面算出来的数字销售不认市场部也不认。2.1 先分清楚渠道层级现代、传统、电商康师傅方便面的渠道通常分三层L1是大盘现代、传统、电商L2是每个大盘下的细分L3一般到具体客户。PPT里最多分析到L2再细分会淹没在噪声里。常见划分如下。渠道L1渠道L2典型客户/场景现代NKA沃尔玛、大润发现代LKA区域连锁超市现代CVS全家、7-11传统批发批发市场档口传统食杂店夫妻老婆店电商B2C天猫旗舰店、京东自营电商O2O美团闪购、京东到家这是很普遍的划分实际以企业内部主数据为准。做分析时渠道字段至少要保证到L2。如果一个经销商既供批发又供食杂店就需要在门店主数据里单独打标不能混用。2.2 五个核心指标口径指标看什么计算口径数值铺货率覆盖广度有该SKU记录的门店数 / 该渠道总门店数加权铺货率覆盖质量有该SKU门店的品类销售额 / 该渠道全部门店品类销售额动销率卖不卖得动期间内有销售记录的门店数 / 有铺货记录的门店数缺货率断供情况结转缺货门店数 / 应陈列门店数货架份额陈列竞争本品货架面数 / 同类商品货架面数电商不适用加权铺货率的重点是给大店更大的权重。比如在A渠道铺了1000家小店在B渠道铺了300家大卖场数值铺货率A渠道更高但加权铺货率B渠道可能反超。方便面高度依赖冲动购买货架位置直接影响动销所以货架份额这个指标不能省。2.3 用Pandas算指标下面这段代码按销售流水和门店主数据算数值铺货率、加权铺货率和动销率。import pandas as pd # 字段store_id 门店, product_id SKU, qty 销量, is_listed 是否有铺货标记 df pd.read_csv(sales_detail.csv, parse_dates[date]) store pd.read_csv(store_master.csv) # 字段store_id, channel_l2, cat_sales df df.merge(store, onstore_id, howleft) # 数值铺货率按渠道和SKU有铺货记录的门店数 / 该渠道总门店数 listed df[df[is_listed] 1].groupby( [channel_l2, product_id])[store_id].nunique().rename(listed_stores) total store.groupby(channel_l2)[store_id].nunique().rename(total_stores) coverage listed.to_frame().join(total, onchannel_l2) coverage[数值铺货率] coverage[listed_stores] / coverage[total_stores] # 加权铺货率有铺货门店的品类销售额 / 该渠道全部门店品类销售额 w_listed df[df[is_listed] 1].groupby( [channel_l2, product_id])[cat_sales].sum().rename(w_listed) w_total store.groupby(channel_l2)[cat_sales].sum().rename(w_total) weighted w_listed.to_frame().join(w_total, onchannel_l2) weighted[加权铺货率] weighted[w_listed] / weighted[w_total] # 动销率有销售记录的门店数 / 有铺货记录的门店数 sell_stores df[df[qty] 0].groupby( [channel_l2, product_id])[store_id].nunique().rename(sell_stores) sellout sell_stores.to_frame().join(listed, howleft) sellout[动销率] sellout[sell_stores] / sellout[listed_stores] print(coverage.head()) print(weighted.head()) print(sellout.head())代码逻辑说明merge用howleft保留流水全部行避免丢订单如果门店主数据没匹配上cat_sales会是空值需要在分析前回填或标记。nunique()是按门店ID去重不是按记录数这是铺货率的关键。如果重复统计铺货率会虚高。动销率的分母是有铺货记录的门店而不是全部门店。这样衡量的是铺上以后卖不卖得动与铺货率互不干扰。想看全品汇总时把product_id去掉即可但建议先按单品看再看聚合避免单品波动被平均掩盖。提示is_listed必须来自初中上架记录或进销存里的铺货单不能用销售大于0反推否则铺货率永远等于动销率指标就失去意义了。3. 渠道数据清洗把ERP流水和经销商报表做成渠道维度表零售数据不会按分析维度摆好等你。ERP里的客户类型、经销商管报里的区域、电商后台的店铺名字段千奇百怪。清洗的目标是形成一张统一的渠道维度表后续指标代码全部依赖这张表。3.1 建立渠道映射表而不是在代码里写replace常见做法是维护一个CSV映射文件新增渠道时只改配置不动代码。下面是一个最小的映射表示例。raw_channel,channel_l1,channel_l2 大润发,现代,NKA 沃尔玛,现代,NKA 华润万家,现代,NKA 全家,现代,CVS 7TT,现代,CVS 批发市场,传统,批发 食杂店,传统,食杂店 天猫旗舰店,电商,B2C 京东自营,电商,B2C 美团闪购,电商,O2O用merge做映射而不是replaceimport pandas as pd map_df pd.read_csv(channel_map.csv) raw pd.read_csv(sales_detail_raw.csv) raw raw.merge(map_df, onraw_channel, howleft) # 查看未匹配的渠道 unmatched raw[raw[channel_l1].isna()] print(unmatched[raw_channel].value_counts(normalizeTrue)) # 未匹配的统一归为“其他”但要记录占比 raw[channel_l1] raw[channel_l1].fillna(其他) raw[channel_l2] raw[channel_l2].fillna(其他)参数说明merge的howleft保留左表全部行。如果某渠道名没有映射对应渠道维度是空值用value_counts(normalizeTrue)看占比。超过1%的渠道必须回填映射说明这个客户很重要不能当脏数据丢掉。不建议用df.replace做一对多映射因为渠道名可能有空格、大小写、前后缀replace的模式会越写越长后期无法维护。3.2 区分出货口径与动销口径避免重复统计方便面的渠道数据至少有两个来源经销商进销存和门店POS。如果混在一起同一个商品可能先算出货再算动销销售额叠了两遍。分析PPT首页必须先写明本页用的是哪个口径。重复检查代码# 同一门店、同一SKU、同一日期、同一批次只应有一条记录 dup_check df.groupby([store_id, product_id, date, batch_no]).size() dups dup_check[dup_check 1] print(f重复记录数: {len(dups)}) # 如果批次字段缺失用下单时间近似判断 df[order_hour] df[date].dt.floor(H) dup_check2 df.groupby([store_id, product_id, order_hour]).size() print(dup_check2[dup_check2 1].head())逻辑说明第一段是精确查重要求有批次号第二段是降级方案以小时粒度近似只看重复规模不作为删数据依据。3.3 时间口径统一春节档和同比的错位方便面有非常强的节日脉冲春节档前后销量占比很高。自然月同比很容易失真去年1月是春节前今年1月是春节后两个月份不可比。常见做法是维护一张春节档日期表把每个自然日映射到对应的销售档期。festival pd.DataFrame({ date: pd.date_range(2024-01-01, 2024-12-31), festival: [春节前] * 40 [春节档] * 20 [节后] * 305 }) # 实际应按农历日期生成映射这里示意 df df.merge(festival, ondate, howleft)说明示例中硬编码了区间实际操作要按农历生成。我的做法是先汇总三年农历腊月十六到正月十五的日期区间做成一个字典再映射不要在分析代码里写死。3.4 同店增长计算现代渠道开新店会抬升销售额传统渠道门店倒闭会让总量下降。如果不剔除开店关店渠道增长率的解释力很弱。同店增长只比较存量门店。cur df[(df[date] 2024-01-01) (df[date] 2024-01-31)] pre df[(df[date] 2023-01-01) (df[date] 2023-01-31)] common set(cur[store_id]) set(pre[store_id]) same_store cur[cur[store_id].isin(common)].groupby(channel_l2)[amount].sum() same_store_pre pre[pre[store_id].isin(common)].groupby(channel_l2)[amount].sum() sss_growth (same_store / same_store_pre - 1).rename(同店增长率) print(sss_growth)注意这里先取交集门店再分别汇总。门店编码在第二年可能变化需要借助门店主数据里的开业日期判断不能用简单的字符串匹配。4. 用Python生成渠道分析PPT从matplotlib图表到pptx文件每周或者每月重复做渠道PPT最烦的不是分析而是粘贴图表。Python可以一次跑完分析和输出保证每周的图表、配色、坐标轴规范一致。4.1 图表选择与业务场景匹配分析目标图表类型为什么渠道销售结构变化100%堆叠柱状图看清占比移动渠道同比增速对比柱线组合图柱看规模线看增速区域×渠道矩阵气泡图三维信息在一页单渠道单月趋势带去年同期的折线图判断季节性4.2 先用matplotlib画图再插入PPTimport pandas as pd import matplotlib.pyplot as plt from pptx import Presentation from pptx.util import Inches import tempfile # 示例汇总数据渠道销售额与增长率 summary pd.DataFrame({ channel: [现代, 传统, 电商], amount: [1250, 980, 730], growth: [3, -5, 12] }) fig, ax plt.subplots(figsize(10, 4)) ax.bar(summary[channel], summary[amount], color[#d71920, #f4a81d, #2c6e9c]) ax.set_title(各渠道销售额万元) ax.set_ylabel(销售额万元) for i, v in enumerate(summary[amount]): ax.text(i, v 10, f{v:.0f}, hacenter) ax.axhline(0, colorgrey, linewidth0.8) plt.tight_layout() # 保存为临时图片后续插入PPT with tempfile.NamedTemporaryFile(suffix.png, deleteFalse) as f: fig.savefig(f.name, dpi200) img_path f.name plt.close() # 创建PPT prs Presentation() slide prs.slides.add_slide(prs.slide_layouts[6]) slide.shapes.add_textbox( Inches(0.6), Inches(0.3), Inches(8), Inches(0.6) ).text_frame.text 渠道销售额对比 slide.shapes.add_picture(img_path, Inches(0.6), Inches(1.0), widthInches(8.5)) prs.save(channel_analysis.pptx)要点说明add_textbox返回的 shape 可以继续往text_frame里加段落先写标题后加图保证不重叠。add_picture只指定width高度会按比例自动计算避免拉伸变形。如果图片本身比例不协调优先在 matplotlib 里用figsize控制长宽比。图片保存成临时文件再插入不要用BytesIO。python-pptx 对BytesIO的支持不太稳定本地路径最稳。4.3 使用python-pptx原生图表方便后续改数据有些场合需要保留可编辑的图表可以在PPT里直接加原生chart。from pptx.chart.data import CategoryChartData from pptx.enum.chart import XL_CHART_TYPE chart_data CategoryChartData() chart_data.categories summary[channel] chart_data.add_series(销售额万元, tuple(summary[amount])) slide prs.slides.add_slide(prs.slide_layouts[6]) graphic_frame slide.shapes.add_chart( XL_CHART_TYPE.COLUMN_CLUSTERED, Inches(0.6), Inches(1.2), Inches(8.0), Inches(4.5), chart_data )参数说明XL_CHART_TYPE.COLUMN_CLUSTERED是簇状柱形图换成折线图用XL_CHART_TYPE.LINE_MARKERS饼图用PIE。位置参数依次是left, top, width, height单位都是Inches()。16:9页面宽度约10英寸留出页边距后图表宽度不要超过9英寸。4.4 图表字体和颜色规范参数建议值原因dpi200投影不虚中文字体微软雅黑或Noto Sans CJK避免PPT显示方框主色不超过3种渠道对比用色相近会分不清图表标题带结论如现代渠道销售额下降5%引导阅读顺序中文字体设置代码plt.rcParams[font.sans-serif] [Microsoft YaHei, Noto Sans CJK SC] plt.rcParams[axes.unicode_minus] False如果不设置matplotlib会显示警告图里中文变成框。axes.unicode_minus关闭减号渲染避免负号变方框。5. 康师傅方便面渠道分析PPT的最后一公里用结论倒排页面数据和图表都有了PPT最后拼的是叙事。渠道分析PPT最容易犯的毛病是把所有图表按时间顺序堆上去汇报十分钟还没讲到重点。我一般会先写结论再倒排页面结构。先用一句话回答三个问题这个月哪些渠道掉量掉量的主因是覆盖问题还是动销问题需要渠道经理下周做什么动作。然后把结论写成标题栏。比如现代渠道掉量5%主因NKA缺货率上升比现代渠道销售分析有用得多。图表注释不要写销售额变化趋势要写红线为平均线12月跌到线下且未修复。在matplotlib里可以用annotate标出异常点ax.annotate( 缺货率上升12个百分点, xy(2, 12), xytext(1.2, 20), arrowpropsdict(arrowstyle-, colorblack) )补充一个快消品渠道分析经常被忽视的细节渠道经理在会议上真正关心的是我还有多少货架要被竞品抢走。所以在PPT的最后放一个下月动作清单把铺货率、动销率、缺货率三个指标直接对应到责任人和动作而不是只放分析结论。自检技巧每页PPT只放一张主图标题是结论图里标注异常点。如果有人提问电商铺货率多少把第一页的快照表翻出来就能答上。快照表列渠道、数值铺货率、加权铺货率、动销率、缺货率、同比增减。这样整个PPT就可以从数据报告变成决策工具。最后再走一遍数据逻辑任何结论都要能在图里找到依据找不到就删掉那一页。本文还有配套的精品资源点击获取
返回列表