kp-027

时序与对比分析:价格与销量洞察

进阶 ≈ 30 分钟 时序分析价格监控环比同比指数化pandas

前置知识

本文基于模型知识整理。

一句话定义

时序分析把按时间采集的价格/销量变成趋势、变价事件与竞品对比;核心手法是重采样聚合、环比同比与基期指数化。

为什么重要

价格监控(kp-030 案例)的价值全在时间维度:单日快照看不出策略,三个月曲线才能看出「大促前偷偷涨价、周一固定降价」这类模式。本篇是把采集数据变成商业结论的主力工具。

前置知识

kp-011(长表 schema:sku_id, ts, price)、kp-025。

核心概念

  • 重采样:日频 → 周均/月均(resample),消除采集抖动。
  • 环比/同比:(x_t − x_{t−1}) / x_{t−1};同比对应上一周期同位。
  • 变价事件:|diff| / 前值 超阈值(如 3%)记为一次价格调整。
  • 指数化对比:各序列除以自身基期值 ×100,使不同价位 SKU 可同图对比。
  • 加权均价:跨 SKU 平均价必须按销量/曝光加权,否则被小众高价品拉偏。

原理与机制

公式组:

环比增速:  g_t = (x_t − x_{t−1}) / x_{t−1}
同比增速:  yoy_t = (x_t − x_{t−k}) / x_{t−k}     # k=周期长度(周数据k=52)
基期指数:  I_t = x_t / x_0 × 100                 # 各序列自比, 消除量纲
变价事件:  |x_t − x_{t−1}| / x_{t−1} > θ(=0.03)  → 记事件

pandas 实现(长表 → 分析):

import pandas as pd

df = pd.read_sql("SELECT sku_id, ts, price FROM prices", conn, parse_dates=["ts"])
daily = (df.set_index("ts")
           .groupby("sku_id")["price"]
           .resample("D").mean().dropna())          # 日均价, 平滑采集噪声

wide = daily.unstack("sku_id")                      # 宽表: 行=日期, 列=SKU
indexed = wide / wide.iloc[0] * 100                 # 基期指数化 → 同图可比
pct = wide.pct_change()                             # 逐日环比
events = pct[pct.abs() > 0.03].stack()              # 变价事件清单

实例或案例

三个月竞品监控(6 个 SKU)经指数化后看出:A 竞品每逢周五稳定降价 4–5%(节奏性促销),自家价格指数同期上行 8%——「被竞品节奏性促销压制」成为有数据支撑的结论,直接进入定价周会(kp-024 的「价格指数」指标闭环)。若无指数化,A 的低价 SKU 与自家高价 SKU 同图会完全失真。

常见误区

  • 误区一:直接平均所有 SKU 的价格。 10 元品与 1000 元品混合均价无业务意义;先分类目,再指数化或加权。
  • 误区二:把采集日当业务日。 周末漏采、节点停采造成的缺口要用重采样补齐后再算增速,否则环比虚高。
  • 误区三:把促销跳变当趋势。 大促价格不是常态价;变价事件应被识别并分层(常态价 / 促销价)后再谈趋势。

自测题

  1. 为什么跨 SKU 对比要指数化?

答:不同 SKU 价格基数不同,绝对涨跌不可比;除以基期 ×100 后只比相对变化,可同图共读。

  1. 变价事件的检测逻辑?

答:相邻期差值的相对幅度超过阈值 θ(常取 3%)记为事件;阈值按品类波动性校准。

  1. resample("D").mean() 解决什么问题?

答:采集频率不均/漏采导致的时间不齐——重采样到统一日粒度并平滑噪声。

与其他知识点的关系

kp-030 的电商案例以本篇为分析主体;kp-029 把结果画成折线与事件标注图;kp-024 的「价格指数」指标即本篇产出的 marts 表。

延伸阅读

pandas 官方「Time series / date functionality」与「Resampling」两节。

相关知识点

学习进度