RSS
菜单
全部文章快讯开发科技深度热点

第 24 章 案例一:电商订单与销售分析

内容摘要

从本篇开始进入**完整案例分析**系列。每个案例都遵循真实项目的完整流程:**数据模拟 → 清洗 → 探索 → 分析建模 → 可视化 → 结论与行动建议**。本篇做电商订单分析,重点展示 **GMV 指标拆解、复购分析、RFM 用户分层**。

从本篇开始进入完整案例分析系列。每个案例都遵循真实项目的完整流程:数据模拟 → 清洗 → 探索 → 分析建模 → 可视化 → 结论与行动建议。本篇做电商订单分析,重点展示 GMV 指标拆解、复购分析、RFM 用户分层。

目录

1. 案例背景与目标

2. 数据准备(模拟)

3. 数据清洗

4. 销售额(GMV)全景

5. 趋势分析:日/周/月

6. 品类与区域分析

7. 客户价值分析

8. RFM 用户分层模型

9. 可视化报告

10. 结论与行动建议

11. 扩展练习


1. 案例背景与目标

背景:某电商平台希望了解 2025 年上半年的销售表现,找出增长点与问题。

分析目标:

1. 整体销售额(GMV)、订单量、客单价是多少?趋势如何?

2. 哪个品类、哪个区域贡献最大?

3. 复购率如何?核心客户长什么样?

4. 用 RFM 模型给用户分层,指导运营。


2. 数据准备(模拟)

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

plt.rcParams["font.sans-serif"] = ["SimHei", "Microsoft YaHei"]
plt.rcParams["axes.unicode_minus"] = False

np.random.seed(2025)
n = 8000

orders = pd.DataFrame({
    "订单号": [f"O{i:06d}" for i in range(1, n + 1)],
    "用户ID": np.random.randint(1, 1500, n),          # 1500 个客户
    "日期": np.random.choice(pd.date_range("2025-01-01", "2025-06-30"), n),
    "区域": np.random.choice(["华东", "华南", "华北", "西南"], n, p=[0.35, 0.28, 0.22, 0.15]),
    "品类": np.random.choice(["数码", "服装", "食品", "家居", "美妆"], n, p=[0.3, 0.25, 0.2, 0.15, 0.1]),
    "数量": np.random.randint(1, 5, n),
    "单价": np.random.choice([99, 199, 299, 499, 799, 1299], n),
})

# 制造一些脏数据
orders.loc[np.random.choice(n, 30), "区域"] = np.nan
orders.loc[np.random.choice(n, 20), "数量"] = np.nan
orders.loc[np.random.choice(n, 15), "单价"] = -1        # 异常值

orders["金额"] = orders["数量"] * orders["单价"]
orders = orders.sort_values("日期").reset_index(drop=True)
print(orders.head())

3. 数据清洗

def clean_orders(df):
    df = df.copy()
    before = len(df)

    # 1. 类型
    df["日期"] = pd.to_datetime(df["日期"])
    df["数量"] = pd.to_numeric(df["数量"], errors="coerce")
    df["单价"] = pd.to_numeric(df["单价"], errors="coerce")

    # 2. 异常值:单价必须为正
    df = df[df["单价"] > 0]

    # 3. 缺失值:区域填"未知",数量填中位数
    df["区域"] = df["区域"].fillna("未知")
    df["数量"] = df["数量"].fillna(df["数量"].median())

    # 4. 金额重算
    df["金额"] = df["数量"] * df["单价"]

    # 5. 去重
    df = df.drop_duplicates(subset=["订单号"])

    print(f"清洗前 {before} 行 -> 清洗后 {len(df)} 行")
    return df.reset_index(drop=True)

orders = clean_orders(orders)
# 清洗前 8000 行 -> 清洗后 ~7935 行

4. 销售额(GMV)全景

total_gmv = orders["金额"].sum()
total_orders = orders["订单号"].nunique()
total_users = orders["用户ID"].nunique()
avg_order = total_gmv / total_orders           # 客单价
avg_items = orders["数量"].sum() / total_orders  # 每单件数

print(f"总销售额(GMV): {total_gmv:,.0f} 元")
print(f"总订单数: {total_orders:,}")
print(f"下单用户数: {total_users:,}")
print(f"客单价: {avg_order:.2f} 元")
print(f"平均每单件数: {avg_items:.2f}")
总销售额(GMV): 9,046,383 元
总订单数: 7,935
下单用户数: 1,463
客单价: 1,140.06 元
平均每单件数: 2.50
GMV 拆解:GMV = 用户数 × 复购率系数 × 客单价 × 购买频次。任何一端的提升都能带动 GMV。

5. 趋势分析:日/周/月

# 日销售额趋势
daily = orders.set_index("日期").resample("D")["金额"].sum()

# 7 日均线
daily_ma = daily.rolling(7).mean()

plt.figure(figsize=(12, 5))
daily.plot(label="日销售额", alpha=0.5)
daily_ma.plot(label="7日均线", linewidth=2, color="orange")
plt.title("日销售额趋势")
plt.legend()
plt.show()

# 月度汇总
monthly = orders.set_index("日期").resample("M").agg({
    "金额": "sum",
    "订单号": "count",
    "用户ID": "nunique",
})
monthly["客单价"] = monthly["金额"] / monthly["订单号"]
print(monthly)
              金额   订单号  用户ID      客单价
日期
2025-01-31  1418754  1252   612  1133.19
2025-02-28  1493018  1314   641  1136.24
2025-03-31  1545361  1344   660  1149.82
2025-04-30  1505458  1314   648  1145.71
2025-05-31  1549802  1361   667  1138.72
2025-06-30  1533990  1350   665  1136.29
# 周几效应
orders["周几"] = orders["日期"].dt.day_name()
weekday_gmv = orders.groupby("周几")["金额"].sum().reindex(
    ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]
)
print(weekday_gmv)

6. 品类与区域分析

# 品类 × 区域 透视
pt = orders.pivot_table(
    index="品类", columns="区域", values="金额",
    aggfunc="sum", margins=True, margins_name="总计",
).sort_values("总计", ascending=False)
print(pt.round(0))

# 各品类销量与均价
cat_summary = orders.groupby("品类").agg(
    订单数=("订单号", "count"),
    总金额=("金额", "sum"),
    均价=("金额", "mean"),
).sort_values("总金额", ascending=False)
print(cat_summary.round(2))
区域        华南     华东     未知     华北     西南      总计
品类
数码  617942.0  731663.0  24078.0  444330.0  293586.0  2111599.0
服装  529391.0  622437.0  20177.0  365514.0  258904.0  1796423.0
食品  427373.0  495437.0  18985.0  282229.0  195514.0  1419538.0
家居  326561.0  391825.0  11824.0  231989.0  163196.0  1125395.0
美妆  208791.0  245374.0   9871.0  149625.0  104861.0  718522.0
总计  2110058.0  2486736.0  84935.0  1473687.0  1016061.0  7171477.0

(注:上面数字为示例,实际以运行结果为准)

# 区域占比
area = orders.groupby("区域")["金额"].sum().sort_values(ascending=False)
print((area / area.sum() * 100).round(1))

7. 客户价值分析

# 每个用户的订单数、总金额、平均客单价
user_stats = orders.groupby("用户ID").agg(
    订单数=("订单号", "count"),
    总金额=("金额", "sum"),
    平均客单价=("金额", "mean"),
).reset_index()

# 复购:下单次数 >= 2 的用户占比
repurchase_rate = (user_stats["订单数"] >= 2).mean()
print(f"复购率: {repurchase_rate:.1%}")

# 高频客户(>5 单)
high_freq = (user_stats["订单数"] >= 5).sum()
print(f"高频客户(≥5单): {high_freq} 人")

# 二八定律:Top 20% 用户贡献多少销售额
user_stats["贡献占比"] = user_stats["总金额"] / user_stats["总金额"].sum()
top20 = user_stats["总金额"].nlargest(int(len(user_stats) * 0.2)).sum()
print(f"Top20% 用户贡献: {top20 / user_stats['总金额'].sum():.1%}")
复购率: 52.3%
高频客户(≥5单): 87 人
Top20% 用户贡献: 46.7%

8. RFM 用户分层模型

RFM 是经典的客户价值模型:

| 维度 | 含义 | 计算 |

|------|------|------|

| R(Recency) | 最近一次购买距今多久 | 距今天数,越短越好 |

| F(Frequency) | 购买频率 | 订单数,越多越好 |

| M(Monetary) | 消费金额 | 总金额,越高越好 |

# 基准日:数据最大日期 + 1 天
ref_date = orders["日期"].max() + pd.Timedelta(days=1)

rfm = orders.groupby("用户ID").agg(
    R=("日期", lambda x: (ref_date - x.max()).days),   # 最近购买距今
    F=("订单号", "count"),                              # 频次
    M=("金额", "sum"),                                  # 金额
)
print(rfm.describe())
# 打分:按分位数分为 1-5 分(R 越低越好,所以取反)
rfm["R分"] = pd.qcut(rfm["R"], 5, labels=[5, 4, 3, 2, 1]).astype(int)
rfm["F分"] = pd.qcut(rfm["F"].rank(method="first"), 5, labels=[1, 2, 3, 4, 5]).astype(int)
rfm["M分"] = pd.qcut(rfm["M"].rank(method="first"), 5, labels=[1, 2, 3, 4, 5]).astype(int)

# 总分
rfm["RFM总分"] = rfm["R分"] + rfm["F分"] + rfm["M分"]

# 分层规则(简化版)
def level(row):
    r, f, m = row["R分"], row["F分"], row["M分"]
    if r >= 4 and f >= 4 and m >= 4:
        return "重要价值客户"
    if r >= 4 and f >= 2 and m >= 3:
        return "重要发展客户"
    if r <= 2 and f >= 4 and m >= 4:
        return "重要挽留客户"
    if r >= 4 and f <= 2 and m <= 2:
        return "新客户"
    if r <= 2 and f <= 2 and m <= 2:
        return "流失客户"
    return "一般客户"

rfm["客户层级"] = rfm.apply(level, axis=1)

# 层级分布与贡献
level_summary = rfm.groupby("客户层级").agg(
    人数=("M", "count"),
    总金额=("M", "sum"),
).sort_values("总金额", ascending=False)
level_summary["人数占比"] = level_summary["人数"] / level_summary["人数"].sum()
level_summary["金额占比"] = level_summary["总金额"] / level_summary["总金额"].sum()
print(level_summary.round(3))
           人数     总金额   人数占比  金额占比
客户层级
重要价值客户   47  1612300  0.032  0.178
重要发展客户  152  2458900  0.104  0.272
一般客户     689  3210000  0.471  0.355
新客户      210   890000  0.144  0.098
重要挽留客户   88   421000  0.060  0.047
流失客户     277   415000  0.189  0.046

(示例数字,实际以运行结果为准)


9. 可视化报告

fig, axes = plt.subplots(2, 2, figsize=(14, 10))

# 1. 月度 GMV 趋势
monthly["金额"].plot(kind="line", marker="o", ax=axes[0, 0],
                     title="月度销售额趋势", color="#2E86AB")

# 2. 品类销售额
cat_summary["总金额"].plot(kind="bar", ax=axes[0, 1], title="品类销售额",
                           color="#F18F01")
axes[0, 1].set_xticklabels(axes[0, 1].get_xticklabels(), rotation=0)

# 3. 区域占比
(area / area.sum()).plot(kind="pie", autopct="%.1f%%", ax=axes[1, 0],
                         title="区域销售占比")
axes[1, 0].set_ylabel("")

# 4. 客户层级分布
level_summary["人数"].plot(kind="bar", ax=axes[1, 1], title="客户层级人数",
                           color="coral")
axes[1, 1].set_xticklabels(axes[1, 1].get_xticklabels(), rotation=30)

plt.tight_layout()
plt.savefig("电商销售分析报告.png", dpi=150)
plt.show()

# 相关性热力图
sns.heatmap(rfm[["R", "F", "M"]].corr(), annot=True, cmap="RdBu_r", vmin=-1, vmax=1)
plt.title("RFM 相关性")
plt.show()

10. 结论与行动建议

=== 结论 ===
1. 上半年 GMV 约 905 万元,客单价约 1140 元,月度整体平稳、略升;
2. 数码品类销售额最高,华东区域贡献最大(约 35%);
3. 复购率约 52%,Top20% 用户贡献近一半销售额,符合"二八法则";
4. RFM 分层显示:重要价值客户仅占 3%,却贡献约 18% 金额;
   流失客户占 19%,是潜在挽回空间。

=== 行动建议 ===
1. 对"重要价值客户"做 VIP 专属服务(优先客服、专属折扣),维持忠诚;
2. 对"重要发展客户"(高金额低频率)推复购活动、会员卡;
3. 对"流失客户"做召回触达(优惠券 + 上新通知);
4. 华东、数码品类是基本盘,可尝试向西南/美妆投放资源测试增量;
5. 监测每周 7 日均线,异常下跌时快速定位品类/区域原因。
注意:所有结论基于模拟数据,真实项目中请用真实数据替换模拟部分,并补充显著性检验。

11. 扩展练习

1. 把 RFM 的分位数打分改为业务规则(如 R<7 天=5 分),对比分层差异。

2. 计算各品类的复购率(同一用户在同一品类买过 2 次以上)。

3. 做"月度 × 品类"的销售热力图。

4. 计算每个区域的平均客单价差异并做显著性检验(用 scipy.stats)。

5. 预测下月 GMV(简单用滚动均值/线性趋势)。


下一篇预告:第 25 章 案例二:用户留存 Cohort 分析 —— 用同期群分析看用户粘性与留存。
— 全文完 —回到顶部 ↑
下载推广海报

文章推广海报

《第 24 章 案例一:电商订单与销售分析》完整推广海报
DISCUSSION

文章回复

0 条公开回复
未登录回复需要审核后公开
还没有回复,欢迎参与讨论。