课程目标

  1. 掌握电商核心业务指标的计算与解读。
  2. 学习使用分组聚合进行多维数据分析。
  3. 完成销售、用户、商品维度的基础分析报告。

核心Skills

  • 指标计算:GMV、客单价、转化率等
  • 分组聚合groupbypivot_table
  • 多维度分析:结构分析、对比分析、趋势分析

课件内容与代码

步骤1:导入库与数据

# 代码文件:day3_descriptive_analysis.ipynb
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
plt.style.use('seaborn-v0_8-darkgrid')

# 读取清洗后的数据
df = pd.read_csv('cleaned_orders.csv', encoding='utf-8')
# 确保日期格式
if 'order_date' in df.columns:
    df['order_date'] = pd.to_datetime(df['order_date'])
print(f">>> 数据加载成功!形状: {df.shape}")
display(df.head())

步骤2:计算电商核心业务指标

print("="*70)
print("【步骤1:计算核心电商业务指标】")
print("="*70)
# 假设数据时间范围
start_date = df['order_date'].min()
end_date = df['order_date'].max()
days = (end_date - start_date).days + 1

# 1. 总销售额 (GMV)
total_gmv = df['total_amount'].sum()
print(f"1. 总销售额(GMV): ¥{total_gmv:,.2f}")

# 2. 总订单数
total_orders = df['order_id'].nunique()
print(f"2. 总订单数: {total_orders:,}")

# 3. 总用户数
total_users = df['user_id'].nunique()
print(f"3. 总用户数: {total_users:,}")

# 4. 客单价 (Average Order Value)
aov = total_gmv / total_orders if total_orders > 0 else 0
print(f"4. 客单价(AOV): ¥{aov:,.2f}")

# 5. 人均订单数 (订单频次)
orders_per_user = total_orders / total_users if total_users > 0 else 0
print(f"5. 人均订单数: {orders_per_user:.2f}")

# 6. 日均销售额
daily_gmv = total_gmv / days
print(f"6. 日均销售额: ¥{daily_gmv:,.2f}")

# 7. 日均订单数
daily_orders = total_orders / days
print(f"7. 日均订单数: {daily_orders:.2f}")

# 8. 汇总输出
summary_dict = {
    '指标': ['总销售额(GMV)', '总订单数', '总用户数', '客单价(AOV)', '人均订单数', '日均销售额', '日均订单数', '数据周期(天)'],
    '数值': [f'¥{total_gmv:,.2f}', f'{total_orders:,}', f'{total_users:,}', f'¥{aov:,.2f}',
            f'{orders_per_user:.2f}', f'¥{daily_gmv:,.2f}', f'{daily_orders:.2f}', f'{days}']
}
summary_df = pd.DataFrame(summary_dict)
print("\n>>> 核心指标汇总表:")
display(summary_df)

步骤3:销售趋势分析(按时间)

print("="*70)
print("【步骤2:销售趋势分析 (按日/月)】")
print("="*70)
# 按日聚合销售额和订单数
daily_sales = df.groupby(df['order_date'].dt.date).agg({
    'total_amount': 'sum',
    'order_id': 'nunique',
    'user_id': 'nunique'
}).rename(columns={'total_amount': 'daily_gmv', 'order_id': 'order_count', 'user_id': 'user_count'})

print(">>> 每日销售数据前5天:")
display(daily_sales.head())

# 绘制趋势图
fig, axes = plt.subplots(2, 1, figsize=(14, 10))
# GMV趋势
axes[0].plot(daily_sales.index, daily_sales['daily_gmv'], marker='o', linewidth=2, color='royalblue')
axes[0].set_title('每日销售额(GMV)趋势', fontsize=15)
axes[0].set_ylabel('销售额 (元)', fontsize=12)
axes[0].grid(True, alpha=0.3)
# 订单数趋势
axes[1].plot(daily_sales.index, daily_sales['order_count'], marker='s', linewidth=2, color='coral')
axes[1].set_title('每日订单数趋势', fontsize=15)
axes[1].set_xlabel('日期', fontsize=12)
axes[1].set_ylabel('订单数', fontsize=12)
axes[1].grid(True, alpha=0.3)
plt.tight_layout()
plt.show()

# 按月聚合
df['order_month'] = df['order_date'].dt.to_period('M')  # 生成‘2023-10’格式
monthly_sales = df.groupby('order_month').agg({
    'total_amount': 'sum',
    'order_id': 'nunique',
    'user_id': 'nunique'
}).rename(columns={'total_amount': 'monthly_gmv', 'order_id': 'order_count', 'user_id': 'user_count'})
print(">>> 月度销售数据:")
display(monthly_sales)

步骤4:商品维度分析

print("="*70)
print("【步骤3:商品维度分析】")
print("="*70)
# 1. 商品销售额排名
product_sales = df.groupby('product_id').agg({
    'total_amount': 'sum',
    'quantity': 'sum',
    'order_id': 'nunique'
}).rename(columns={'total_amount': 'sales_amount', 'quantity': 'sales_volume', 'order_id': 'order_count'})

product_sales = product_sales.sort_values('sales_amount', ascending=False)
print(">>> 商品销售额Top 10:")
display(product_sales.head(10))

# 2. 商品类别分析
category_analysis = df.groupby('category').agg({
    'total_amount': 'sum',
    'order_id': 'nunique',
    'gross_profit': 'sum'
}).rename(columns={'total_amount': 'category_gmv', 'order_id': 'order_count', 'gross_profit': 'total_profit'})
category_analysis['gmv_share'] = (category_analysis['category_gmv'] / category_analysis['category_gmv'].sum() * 100).round(2)
category_analysis = category_analysis.sort_values('category_gmv', ascending=False)
print(">>> 商品类别贡献分析:")
display(category_analysis)

# 3. 绘制类别销售额占比饼图
plt.figure(figsize=(10, 8))
plt.pie(category_analysis['category_gmv'], labels=category_analysis.index,
        autopct='%1.1f%%', startangle=90, colors=sns.color_palette('Set3'))
plt.title('各商品类别销售额占比', fontsize=16)
plt.show()

步骤5:用户维度分析

print("="*70)
print("【步骤4:用户维度分析】")
print("="*70)
# 1. 用户消费金额分布
user_spending = df.groupby('user_id').agg({
    'total_amount': 'sum',
    'order_id': 'nunique',
    'order_date': lambda x: (x.max() - x.min()).days if len(x) > 1 else 0  # 购买跨度
}).rename(columns={'total_amount': 'user_lifetime_value', 'order_id': 'purchase_count', 'order_date': 'purchase_span_days'})

print(">>> 用户消费行为统计描述:")
display(user_spending.describe())

# 2. RFM模型简化版:计算每个用户的最近购买时间(R)、购买频次(F)、消费金额(M)
# 假设分析日期为数据最后一天
analysis_date = df['order_date'].max()
rfm_data = df.groupby('user_id').agg({
    'order_date': lambda x: (analysis_date - x.max()).days,  # R: 最近一次购买距今天数
    'order_id': 'nunique',                                   # F: 购买次数
    'total_amount': 'sum'                                    # M: 总消费金额
}).rename(columns={'order_date': 'recency', 'order_id': 'frequency', 'total_amount': 'monetary'})

print(">>> 用户RFM数据前10行:")
display(rfm_data.head(10))

# 3. 用户城市分布
user_city_dist = df.groupby('city').agg({
    'user_id': 'nunique',
    'total_amount': 'sum'
}).rename(columns={'user_id': 'user_count', 'total_amount': 'city_gmv'}).sort_values('city_gmv', ascending=False)
print(">>> 用户城市分布与贡献:")
display(user_city_dist)

步骤6:交叉分析与数据透视表

print("="*70)
print("【步骤5:交叉分析与数据透视表】")
print("="*70)
# 1. 使用 groupby 进行多维度交叉
# 例如:查看各城市、各商品类别的销售额
cross_city_category = df.groupby(['city', 'category'])['total_amount'].sum().unstack(fill_value=0)
print(">>> 各城市 x 各商品类别 销售额交叉表 (部分):")
display(cross_city_category.head())

# 2. 使用 pivot_table 进行更灵活的分析
# 计算每个城市每月的订单数
pivot_monthly_city = pd.pivot_table(df,
                                     values='order_id',
                                     index=df['order_date'].dt.to_period('M'),
                                     columns='city',
                                     aggfunc='count',
                                     fill_value=0)
print(">>> 数据透视表:各城市每月订单数")
display(pivot_monthly_city)

# 3. 计算每个用户在不同类别的消费金额占比(用户-类别矩阵)
user_category_pivot = pd.pivot_table(df,
                                      values='total_amount',
                                      index='user_id',
                                      columns='category',
                                      aggfunc='sum',
                                      fill_value=0)
print(">>> 用户-商品类别消费矩阵 (前5个用户):")
display(user_category_pivot.head())

步骤7:结构分析与贡献度分析(帕累托分析)

print("="*70)
print("【步骤6:结构分析与帕累托分析】")
print("="*70)
# 1. 商品销售额的帕累托分析 (二八法则)
product_sales_sorted = product_sales.sort_values('sales_amount', ascending=False)
product_sales_sorted['cumulative_sales'] = product_sales_sorted['sales_amount'].cumsum()
product_sales_sorted['cumulative_percentage'] = (product_sales_sorted['cumulative_sales'] / product_sales_sorted['sales_amount'].sum() * 100).round(2)

print(">>> 商品销售额帕累托分析 (Top 20商品):")
display(product_sales_sorted.head(20)[['sales_amount', 'cumulative_sales', 'cumulative_percentage']])

# 找出贡献80%销售额的商品
top_80_percent = product_sales_sorted[product_sales_sorted['cumulative_percentage'] <= 80]
print(f">>> 贡献80%销售额的商品数量: {len(top_80_percent)} / {len(product_sales_sorted)}")
print(f">>> 这些商品占总商品数的比例: {len(top_80_percent)/len(product_sales_sorted)*100:.1f}%")

# 2. 可视化帕累托图
fig, ax1 = plt.subplots(figsize=(12, 6))
ax1.bar(range(len(product_sales_sorted.head(20))), product_sales_sorted.head(20)['sales_amount'], color='skyblue', label='销售额')
ax1.set_xlabel('商品 (按销售额降序排列)')
ax1.set_ylabel('销售额 (元)', color='skyblue')
ax1.tick_params(axis='y', labelcolor='skyblue')
ax2 = ax1.twinx()
ax2.plot(range(len(product_sales_sorted.head(20))), product_sales_sorted.head(20)['cumulative_percentage'],
         color='orange', marker='o', linewidth=2, label='累计占比')
ax2.set_ylabel('累计销售额占比 (%)', color='orange')
ax2.tick_params(axis='y', labelcolor='orange')
ax2.axhline(y=80, color='red', linestyle='--', linewidth=1, label='80% 线')
plt.title('商品销售额帕累托图 (Top 20)', fontsize=15)
fig.legend(loc='upper left', bbox_to_anchor=(0.1, 0.9))
plt.tight_layout()
plt.show()

步骤8:生成简易分析报告

print("="*70)
print("【步骤7:生成简易分析报告摘要】")
print("="*70)
report_lines = []
report_lines.append("="*50)
report_lines.append("        电商运营数据简易分析报告")
report_lines.append("="*50)
report_lines.append(f"分析周期: {start_date.date()} 至 {end_date.date()} (共{days}天)")
report_lines.append(f"总销售额(GMV): ¥{total_gmv:,.2f}")
report_lines.append(f"总订单数: {total_orders:,} | 总用户数: {total_users:,}")
report_lines.append(f"客单价(AOV): ¥{aov:,.2f} | 人均订单数: {orders_per_user:.2f}")
report_lines.append("-"*50)
report_lines.append("【商品维度】")
top_category = category_analysis.index
report_lines.append(f"  销售额最高的类别: {top_category} (¥{category_analysis.loc[top_category, 'category_gmv']:,.2f})")
top_product = product_sales.index
report_lines.append(f"  销售额最高的单品: {top_product} (¥{product_sales.loc[top_product, 'sales_amount']:,.2f})")
report_lines.append("-"*50)
report_lines.append("【用户维度】")
avg_user_value = user_spending['user_lifetime_value'].mean()
report_lines.append(f"  用户平均生命周期价值(LTV): ¥{avg_user_value:,.2f}")
top_city = user_city_dist.index
report_lines.append(f"  贡献最大的城市: {top_city} (用户数: {user_city_dist.loc[top_city, 'user_count']:,})")
report_lines.append("-"*50)
report_lines.append("【关键发现】")
report_lines.append(f"  1. {top_category} 是核心销售品类,贡献了 {category_analysis.loc[top_category, 'gmv_share']}% 的GMV。")
report_lines.append(f"  2. 头部{len(top_80_percent)}个商品贡献了80%的销售额。")
report_lines.append("="*50)

for line in report_lines:
    print(line)

# 可选:将报告保存为文本文件
with open('daily_analysis_report.txt', 'w', encoding='utf-8') as f:
    f.write('\n'.join(report_lines))
print(">>> 分析报告已保存至 'daily_analysis_report.txt'")

本日要点总结

  1. 核心指标:GMV、订单数、用户数、客单价(AOV)、人均订单数是电商分析基石。
  2. 趋势分析:按日、周、月聚合数据,使用折线图观察业务走势。
  3. 维度拆分:从商品(品类、单品)、用户(城市、价值)、时间等多个维度切入分析。
  4. 分组聚合df.groupby() 是维度分析的灵魂,可配合多种聚合函数。
  5. 交叉分析pd.pivot_table() 功能强大,可轻松制作多维交叉报表。
  6. 结构分析:帕累托图(二八分析)帮助识别核心贡献商品/用户。
  7. 报告输出:将分析结果提炼成简洁明了的文字报告,是数据工作的最终价值体现。

课程总结与后续预告

第1-3天我们构建了电商数据分析的基础工作流

  1. Day1 获取:搭建环境,从文件获取原始数据。
  2. Day2 清洗:处理脏数据,为分析准备好“干净食材”。
  3. Day3 分析:计算核心指标,进行多维度描述性分析,产出初步洞察。

关键函数与版本

  • Pandas (pd.read_csvpd.read_exceldf.groupbypd.pivot_tablepd.mergepd.cut)
  • NumPy (基础数值计算)
  • Matplotlib/Seaborn (plt.plotplt.pieplt.barsns.set_style)
  • Scikit-learn (MinMaxScalerStandardScaler – 用于标准化)
  • 建议版本:pandas>=1.3.0, numpy>=1.20.0, matplotlib>=3.4.0, scikit-learn>=0.24.0

运行说明

  1. 确保已安装Python(>=3.7)和Jupyter Notebook。
  2. 按顺序执行每日的代码单元格。
  3. 案例数据脚本已包含在代码中,首次运行时会自动生成示例CSV和Excel文件。
  4. 所有输出文件(如cleaned_orders.csvdaily_analysis_report.txt)将保存在当前工作目录。

后续课程预告

  • 第4-6天:深入可视化与探索性数据分析(EDA)
  • 第7-9天:流量与转化漏斗分析
  • 第10-15天:用户行为分析与RFM模型实战
  • 第16-24天:销售预测与库存分析模型
  • 第25-30天:搭建自动化报表系统与项目整合

通过这3天的学习,您已经掌握了电商数据分析的完整基础流程,并能够独立完成从数据获取到生成基础分析报告的全过程。接下来的课程将在此基础上,向更深度的分析和更自动化的应用迈进。