母婴商品销售数据可视化分析:从数据到洞察的完整实践
·
母婴商品销售数据可视化分析:从数据到洞察的完整实践
引言
在当今数字化时代,数据分析已经成为企业决策的重要依据。对于电商平台而言,深入分析销售数据不仅能帮助企业了解市场趋势,还能优化商品结构、提升用户体验。本文将分享一个完整的母婴商品销售数据可视化分析项目,从数据获取、清洗到最终的可视化展示和商业洞察,为大家提供一个实用的数据分析实践案例。
项目背景
本次分析基于天猫母婴商品销售数据集,包含 2012 年至 2015 年的交易记录和用户信息。通过对这些数据的深入分析,我们可以揭示母婴商品市场的发展趋势、用户购买行为特征以及商品销售规律,为电商平台的运营决策提供数据支撑。
实验目标
- 掌握数据可视化工具:通过实际操作熟练运用 Matplotlib、Seaborn 等可视化库
- 数据处理能力提升:学习针对销售数据的清洗、转换和特征工程方法
- 分析思维培养:从多角度分析销售数据,挖掘潜在商业价值
- 报告撰写能力:将分析结果转化为清晰、有价值的商业洞察
实验环境
- 硬件:PC 微机
- 软件:Jupyter Notebook、Conda 23.7.4
- 编程语言:Python 3.11.5
- 核心库:NumPy、Pandas、Matplotlib、Seaborn
完整分析代码
环境配置和库导入
#!/usr/bin/env python
# coding: utf-8
# ==============================
# 实验七:母婴商品销售数据可视化分析
# 广州工商学院 数据可视化与Matplotlib课程
# ==============================
# ==================== 第一部分:环境配置和库导入 ====================
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import warnings
from datetime import datetime, timedelta
import matplotlib.cm as cm
# 设置中文字体
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei', 'SimHei'] # Windows
# plt.rcParams['font.sans-serif'] = ['Arial Unicode MS'] # Mac
plt.rcParams['axes.unicode_minus'] = False
# plt.style.use('seaborn-whitegrid')
# 忽略警告
warnings.filterwarnings('ignore')
print("✅ 环境配置完成")
数据读取与初步探索
# ==================== 第二部分:数据读取与初步探索 ====================
print("\n" + "="*60)
print("开始读取数据...")
# 读取交易数据和母婴信息数据
try:
trade_df = pd.read_csv('./大作业/(sample)sam_tianchi_mum_baby_trade_history.csv')
baby_df = pd.read_csv('./大作业/(sample)sam_tianchi_mum_baby.csv')
print(f"✅ 数据读取成功!交易数据形状:{trade_df.shape},母婴数据形状:{baby_df.shape}")
except FileNotFoundError as e:
print(f"❌ 文件未找到:{e}")
print("请确保以下文件存在:")
print("1. (sample)sam_tianchi_mum_baby_trade_history.csv")
print("2. (sample)sam_tianchi_mum_baby.csv")
exit()
# 数据基本信息
print("\n🔍 交易数据基本信息:")
print(f"字段列表:{list(trade_df.columns)}")
print(f"数据预览:")
print(trade_df.head())
print(f"\n缺失值统计:")
print(trade_df.isnull().sum())
数据清洗
# ==================== 第三部分:数据清洗 ====================
print("\n" + "="*60)
print("开始数据清洗...")
# 3.1 保留购买量在 [1, 195] 之间的订单
original_count = trade_df.shape[0]
trade_df = trade_df[(trade_df['buy_mount'] >= 1) & (trade_df['buy_mount'] <= 195)].copy()
print(f"✅ 购买量筛选:{original_count} → {trade_df.shape[0]} 条记录")
# 3.2 处理缺失值
trade_df.dropna(inplace=True)
print(f"✅ 删除缺失值后:{trade_df.shape[0]} 条记录")
# 3.3 重命名字段
trade_df.rename(columns={'auction_id': 'item_id'}, inplace=True)
print("✅ 已将 auction_id 重命名为 item_id")
# 3.4 删除 property 列
if 'property' in trade_df.columns:
trade_df.drop('property', axis=1, inplace=True)
print("✅ 已删除 property 列")
# 3.5 日期格式转换
trade_df['day'] = pd.to_datetime(trade_df['day'], format='%Y%m%d')
print("✅ 已将 day 转换为日期格式")
# 3.6 提取时间特征
trade_df['year'] = trade_df['day'].dt.year
trade_df['quarter'] = trade_df['day'].dt.quarter
trade_df['month'] = trade_df['day'].dt.month
trade_df['date'] = trade_df['day'].dt.date
trade_df['year_month'] = trade_df['day'].dt.strftime('%Y-%m')
trade_df['year_quarter'] = trade_df['year'].astype(str) + '-Q' + trade_df['quarter'].astype(str)
print("✅ 数据清洗完成!")
基础分布分析
# ==================== 第四部分:图表1 - 单个订单购买量分布 ====================
print("\n" + "="*60)
print("生成图表1:单个订单购买量分布...")
plt.figure(figsize=(10, 6))
amount_count = trade_df['buy_mount'].value_counts().sort_index()
plt.scatter(amount_count.index, amount_count.values, c='steelblue', s=50, alpha=0.7)
plt.title('单个订单购买量分布', fontsize=16, fontweight='bold', pad=15)
plt.xlabel('购买量(件)', fontsize=12)
plt.ylabel('订单数', fontsize=12)
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.savefig('图1_单个订单购买量分布.png', dpi=300, bbox_inches='tight')
plt.show()
print(f"📊 购买量统计:")
print(f" 最小购买量:{trade_df['buy_mount'].min()}")
print(f" 最大购买量:{trade_df['buy_mount'].max()}")
print(f" 平均购买量:{trade_df['buy_mount'].mean():.2f}")
整体市场趋势分析
python
# ==================== 第五部分:整体市场分析(年、季、月趋势) ====================
print("\n" + "="*60)
print("生成整体市场分析图表...")
# 5.1 年销量趋势
plt.figure(figsize=(10, 6))
year_sales = trade_df.groupby('year')['buy_mount'].sum().reset_index()
year_sales = year_sales[year_sales['year'].between(2012, 2015)]
plt.bar(year_sales['year'], year_sales['buy_mount'],
color=['#4C72B0', '#55A868', '#C44E52', '#8172B3'],
alpha=0.8, edgecolor='black')
# 标注数值
for i, (year, sales) in enumerate(zip(year_sales['year'], year_sales['buy_mount'])):
plt.text(year, sales + 500, f'{int(sales)}',
ha='center', va='bottom', fontsize=10, fontweight='bold')
plt.title('母婴商品年销量趋势(2012-2015)', fontsize=16, fontweight='bold', pad=15)
plt.xlabel('年份', fontsize=12)
plt.ylabel('销量(件)', fontsize=12)
plt.xticks(year_sales['year'])
plt.grid(True, alpha=0.3, axis='y')
plt.tight_layout()
plt.savefig('图2_年销量趋势.png', dpi=300, bbox_inches='tight')
plt.show()
# 5.2 季度销量趋势
plt.figure(figsize=(14, 7))
quarter_sales = trade_df.groupby('year_quarter')['buy_mount'].sum().reset_index()
quarter_sales = quarter_sales.sort_values('year_quarter')
# 定义季度列表(按实验要求)
quarter_order = ['2012-Q3', '2012-Q4', '2013-Q1', '2013-Q2', '2013-Q3', '2013-Q4',
'2014-Q1', '2014-Q2', '2014-Q3', '2014-Q4', '2015-Q1']
quarter_sales['year_quarter'] = pd.Categorical(quarter_sales['year_quarter'],
categories=quarter_order,
ordered=True)
quarter_sales = quarter_sales.sort_values('year_quarter')
colors = plt.cm.Set3(np.linspace(0, 1, len(quarter_sales)))
bars = plt.bar(range(len(quarter_sales)), quarter_sales['buy_mount'],
color=colors, alpha=0.8, edgecolor='black')
# 标注数值
for i, (quarter, sales) in enumerate(zip(quarter_sales['year_quarter'], quarter_sales['buy_mount'])):
plt.text(i, sales + 200, f'{int(sales)}', ha='center', va='bottom',
fontsize=9, fontweight='bold', rotation=45)
plt.title('母婴商品季度销量趋势', fontsize=16, fontweight='bold', pad=15)
plt.xlabel('(年,季度)', fontsize=12)
plt.ylabel('销量(件)', fontsize=12)
plt.xticks(range(len(quarter_sales)), quarter_sales['year_quarter'], rotation=45)
plt.grid(True, alpha=0.3, axis='y')
plt.tight_layout()
plt.savefig('图3_季度销量趋势.png', dpi=300, bbox_inches='tight')
plt.show()
# 5.3 月销量趋势
plt.figure(figsize=(16, 8))
monthly_sales = trade_df.groupby('year_month')['buy_mount'].sum().reset_index()
monthly_sales['year_month_dt'] = pd.to_datetime(monthly_sales['year_month'] + '-01')
monthly_sales = monthly_sales.sort_values('year_month_dt')
plt.plot(monthly_sales['year_month'], monthly_sales['buy_mount'],
marker='o', markersize=6, linewidth=2.5, color='#2E86AB')
plt.fill_between(monthly_sales['year_month'], monthly_sales['buy_mount'],
alpha=0.2, color='#2E86AB')
# 标注高点月份
highlight_months = ['2012-06', '2012-11', '2013-05', '2013-11', '2014-05', '2014-11']
for idx, row in monthly_sales.iterrows():
if row['year_month'] in highlight_months:
plt.text(idx, row['buy_mount'] + 150, f'{int(row["buy_mount"])}',
ha='center', va='bottom', fontsize=10, fontweight='bold',
bbox=dict(boxstyle='round,pad=0.3', facecolor='yellow', alpha=0.7))
plt.title('母婴商品月销量趋势(2012-2015)', fontsize=16, fontweight='bold', pad=15)
plt.xlabel('月份', fontsize=12)
plt.ylabel('销量(件)', fontsize=12)
plt.xticks(range(0, len(monthly_sales), 3), monthly_sales['year_month'][::3], rotation=45)
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.savefig('图4_月销量趋势.png', dpi=300, bbox_inches='tight')
plt.show()
第一季度销售分析
python
# ==================== 第六部分:第一季度销售分析 ====================
print("\n" + "="*60)
print("分析第一季度销售情况...")
def plot_q1_analysis(year):
"""绘制指定年份第一季度的销量和用户量趋势"""
q1_data = trade_df[(trade_df['year'] == year) & (trade_df['quarter'] == 1)].copy()
daily_agg = q1_data.groupby('date').agg(
销量=('buy_mount', 'sum'),
用户量=('user_id', 'nunique')
).reset_index()
fig, ax1 = plt.subplots(figsize=(14, 6))
# 销量折线
color1 = 'tab:blue'
ax1.plot(daily_agg['date'], daily_agg['销量'],
color=color1, marker='o', markersize=4, linewidth=2, label='销量')
ax1.set_xlabel('日期', fontsize=12)
ax1.set_ylabel('销量(件)', fontsize=12, color=color1)
ax1.tick_params(axis='y', labelcolor=color1)
# 用户量折线
ax2 = ax1.twinx()
color2 = 'tab:green'
ax2.plot(daily_agg['date'], daily_agg['用户量'],
color=color2, marker='s', markersize=4, linewidth=2, label='用户量')
ax2.set_ylabel('用户量(人)', fontsize=12, color=color2)
ax2.tick_params(axis='y', labelcolor=color2)
# 春节标注(2013年春节:2月10日,2014年春节:1月31日)
spring_festival = {'2013': '2013-02-10', '2014': '2014-01-31'}
if str(year) in spring_festival:
sf_date = pd.to_datetime(spring_festival[str(year)])
ax1.axvline(x=sf_date, color='red', linestyle='--', alpha=0.7, linewidth=1.5)
ax1.text(sf_date, ax1.get_ylim()[1]*0.9, '春节',
fontsize=10, color='red', ha='center',
bbox=dict(boxstyle='round,pad=0.2', facecolor='white', alpha=0.8))
plt.title(f'{year}年第一季度销量与用户量趋势', fontsize=16, fontweight='bold', pad=15)
fig.tight_layout()
plt.savefig(f'图5_{year}年第一季度销量用户量趋势.png', dpi=300, bbox_inches='tight')
plt.show()
return daily_agg
# 绘制2013年和2014年第一季度分析
q1_2013 = plot_q1_analysis(2013)
q1_2014 = plot_q1_analysis(2014)
第四季度销售分析
# ==================== 第七部分:第四季度销售分析 ====================
print("\n" + "="*60)
print("分析第四季度销售情况...")
def plot_q4_analysis(year):
"""绘制指定年份第四季度的销量和用户量趋势"""
q4_data = trade_df[(trade_df['year'] == year) & (trade_df['quarter'] == 4)].copy()
daily_agg = q4_data.groupby('date').agg(
销量=('buy_mount', 'sum'),
用户量=('user_id', 'nunique')
).reset_index()
fig, ax1 = plt.subplots(figsize=(14, 6))
# 销量折线
color1 = 'tab:blue'
ax1.plot(daily_agg['date'], daily_agg['销量'],
color=color1, marker='o', markersize=4, linewidth=2, label='销量')
ax1.set_xlabel('日期', fontsize=12)
ax1.set_ylabel('销量(件)', fontsize=12, color=color1)
ax1.tick_params(axis='y', labelcolor=color1)
# 用户量折线
ax2 = ax1.twinx()
color2 = 'tab:green'
ax2.plot(daily_agg['date'], daily_agg['用户量'],
color=color2, marker='s', markersize=4, linewidth=2, label='用户量')
ax2.set_ylabel('用户量(人)', fontsize=12, color=color2)
ax2.tick_params(axis='y', labelcolor=color2)
# 双十一标注
double11_date = pd.to_datetime(f'{year}-11-11')
ax1.axvline(x=double11_date, color='orange', linestyle='--', alpha=0.7, linewidth=1.5)
ax1.text(double11_date, ax1.get_ylim()[1]*0.9, '双十一',
fontsize=10, color='orange', ha='center',
bbox=dict(boxstyle='round,pad=0.2', facecolor='white', alpha=0.8))
plt.title(f'{year}年第四季度销量与用户量趋势', fontsize=16, fontweight='bold', pad=15)
fig.tight_layout()
plt.savefig(f'图6_{year}年第四季度销量用户量趋势.png', dpi=300, bbox_inches='tight')
plt.show()
return daily_agg
# 绘制2012-2014年第四季度分析
for year in [2012, 2013, 2014]:
plot_q4_analysis(year)
复购率分析
# ==================== 第八部分:复购率分析(已修改) ====================
print("\n" + "="*60)
print("分析用户复购率...")
# 8.1 月复购率趋势
df_1314 = trade_df[trade_df['year'].isin([2013, 2014])].copy()
df_1314['year_month'] = df_1314['day'].dt.strftime('%Y-%m')
# 计算每月每个用户的购买次数(订单行数)
user_month_purchase = df_1314.groupby(['year_month', 'user_id']).size().reset_index(name='purchase_count')
# 按年月聚合:总用户数 + 当月复购用户数(购买次数≥2)
monthly_repurchase = user_month_purchase.groupby('year_month').agg(
总用户数=('user_id', 'nunique'), # 当月总独立用户数
复购用户数=('purchase_count', lambda x: (x >= 2).sum()) # 当月购买≥2次的用户数
).reset_index()
# 计算当月复购率 + 按时间排序
monthly_repurchase['当月复购率'] = monthly_repurchase['复购用户数'] / monthly_repurchase['总用户数']
monthly_repurchase['year_month_dt'] = pd.to_datetime(monthly_repurchase['year_month'] + '-01') # 转日期便于排序
monthly_repurchase = monthly_repurchase.sort_values('year_month_dt').reset_index(drop=True)
# 拆分2013/2014年数据(用于双折线对比)
rep_2013 = monthly_repurchase[monthly_repurchase['year_month_dt'].dt.year == 2013].reset_index(drop=True)
rep_2014 = monthly_repurchase[monthly_repurchase['year_month_dt'].dt.year == 2014].reset_index(drop=True)
# 绘制当月复购率双折线图
plt.figure(figsize=(14, 7))
# 绘制2013年当月复购率
plt.plot(
rep_2013['year_month_dt'].dt.strftime('%m月'), # x轴:仅显示月份(如01月)
rep_2013['当月复购率'],
color='#2E86AB', # 深蓝色,区分度高
marker='o', markersize=6, markerfacecolor='white', markeredgewidth=2, # 空心标记,更醒目
linewidth=2.5, label='2013年当月复购率'
)
# 绘制2014年当月复购率
plt.plot(
rep_2014['year_month_dt'].dt.strftime('%m月'),
rep_2014['当月复购率'],
color='#E63946', # 红色,对比明显
marker='s', markersize=6, markerfacecolor='white', markeredgewidth=2,
linewidth=2.5, label='2014年当月复购率'
)
plt.title('2013-2014年月度当月复购率变化趋势(母婴品类)', fontsize=16, fontweight='bold', pad=20)
plt.xlabel('月份', fontsize=12, fontweight='medium')
plt.ylabel('当月复购率(当月购买≥2次用户数/当月总用户数)', fontsize=12, fontweight='medium')
# 图例+网格优化
plt.legend(loc='upper right', fontsize=11, frameon=True, shadow=True)
plt.grid(axis='y', alpha=0.3, linestyle='--') # 仅y轴网格,辅助读取数值
plt.tight_layout()
plt.savefig('图7_2013-2014年当月复购率趋势图.png', dpi=300, bbox_inches='tight', facecolor='white')
plt.show()
print("=== 2013-2014年当月复购率核心数据 ===")
print(monthly_repurchase[['year_month', '总用户数', '复购用户数', '当月复购率']].round(6))
# 8.2 各大类复购率(保持原逻辑)
df_cat = trade_df[trade_df['cat1'].notna()].copy()
cat_user_purchase = df_cat.groupby(['cat1', 'user_id']).size().reset_index(name='purchase_count')
cat_repurchase = cat_user_purchase.groupby('cat1').agg(
总用户数=('user_id', 'nunique'),
复购用户数=('purchase_count', lambda x: (x >= 2).sum())
).reset_index()
cat_repurchase['复购率'] = cat_repurchase['复购用户数'] / cat_repurchase['总用户数']
cat_repurchase = cat_repurchase.sort_values('cat1', ascending=True)
plt.figure(figsize=(12, 6))
colors = plt.cm.Set3(np.linspace(0, 1, len(cat_repurchase)))
bars = plt.bar(cat_repurchase['cat1'].astype(str), cat_repurchase['复购率'],
color=colors, alpha=0.8, edgecolor='black')
for bar in bars:
height = bar.get_height()
plt.text(bar.get_x() + bar.get_width()/2., height + 1e-7,
f'{height:.6f}', ha='center', va='bottom', fontsize=9)
plt.title('各大类商品复购率', fontsize=16, fontweight='bold', pad=15)
plt.xlabel('商品大类ID', fontsize=12)
plt.ylabel('复购率', fontsize=12)
plt.grid(True, alpha=0.3, axis='y')
plt.tight_layout()
plt.savefig('图8_各大类商品复购率.png', dpi=300, bbox_inches='tight')
plt.show()
商品销售情况分析
# ==================== 第九部分:商品销售情况分析 ====================
print("\n" + "="*60)
print("分析商品销售情况...")
# 9.1 商品大类销售情况
cat1_sales = trade_df.groupby('cat1').agg(
总销量=('buy_mount', 'sum'),
总用户数=('user_id', 'nunique'),
订单数=('item_id', 'count')
).reset_index()
cat1_sales['人均销量'] = cat1_sales['总销量'] / cat1_sales['总用户数']
cat1_sales = cat1_sales.sort_values('cat1', ascending=True)
plt.figure(figsize=(12, 6))
colors = ['#FF6B6B', '#4ECDC4', '#45B7D1', '#96CEB4', '#FECA57', '#FF9FF3', '#54A0FF']
bars = plt.bar(cat1_sales['cat1'].astype(str), cat1_sales['总销量'],
color=colors[:len(cat1_sales)], alpha=0.8, edgecolor='black')
for bar in bars:
height = bar.get_height()
plt.text(bar.get_x() + bar.get_width()/2., height + height*0.01,
f'{int(height)}', ha='center', va='bottom', fontsize=10, fontweight='bold')
plt.title('商品大类销售情况(总销量)', fontsize=16, fontweight='bold', pad=15)
plt.xlabel('商品大类ID', fontsize=12)
plt.ylabel('总销量(件)', fontsize=12)
plt.grid(True, alpha=0.3, axis='y')
plt.tight_layout()
plt.savefig('图9_商品大类销售情况.png', dpi=300, bbox_inches='tight')
plt.show()
# 9.2 商品大类人均销量
plt.figure(figsize=(12, 6))
bars = plt.bar(cat1_sales['cat1'].astype(str), cat1_sales['人均销量'],
color=['#8172B3', '#C44E52', '#55A868', '#4C72B0'][:len(cat1_sales)],
alpha=0.8, edgecolor='black')
for bar in bars:
height = bar.get_height()
plt.text(bar.get_x() + bar.get_width()/2., height + height*0.01,
f'{height:.2f}', ha='center', va='bottom', fontsize=10, fontweight='bold')
plt.title('商品大类人均销量', fontsize=16, fontweight='bold', pad=15)
plt.xlabel('商品大类ID', fontsize=12)
plt.ylabel('人均销量(件/人)', fontsize=12)
plt.grid(True, alpha=0.3, axis='y')
plt.tight_layout()
plt.savefig('图10_商品大类人均销量.png', dpi=300, bbox_inches='tight')
plt.show()
# 9.3 商品大类子类数量分布
cat1_sub_count = trade_df.groupby('cat1')['cat_id'].nunique().reset_index(name='子类数量')
cat1_sub_count = cat1_sub_count.sort_values('cat1', ascending=True)
plt.figure(figsize=(12, 6))
colors = plt.cm.Paired(np.linspace(0, 1, len(cat1_sub_count)))
bars = plt.bar(cat1_sub_count['cat1'].astype(str), cat1_sub_count['子类数量'],
color=colors, alpha=0.8, edgecolor='black')
for bar in bars:
height = bar.get_height()
plt.text(bar.get_x() + bar.get_width()/2., height + 0.1,
f'{int(height)}', ha='center', va='bottom', fontsize=10, fontweight='bold')
plt.title('商品大类子类数量分布', fontsize=16, fontweight='bold', pad=15)
plt.xlabel('商品大类ID', fontsize=12)
plt.ylabel('子类数量(个)', fontsize=12)
plt.grid(True, alpha=0.3, axis='y')
plt.tight_layout()
plt.savefig('图11_商品大类子类数量分布.png', dpi=300, bbox_inches='tight')
plt.show()
分析总结
# ==================== 第十部分:分析总结 ====================
print("\n" + "="*60)
print("📊 分析总结")
print("="*60)
# 总销量统计
total_sales = trade_df['buy_mount'].sum()
date_range = f"{trade_df['day'].min().strftime('%Y/%m/%d')} - {trade_df['day'].max().strftime('%Y/%m/%d')}"
print(f"📈 总体销售情况:")
print(f" 统计期间:{date_range}")
print(f" 总销量:{total_sales:,} 件")
print(f" 总订单数:{trade_df.shape[0]:,} 笔")
print(f" 总用户数:{trade_df['user_id'].nunique():,} 人")
print(f" 平均订单购买量:{trade_df['buy_mount'].mean():.2f} 件/单")
# 年度销售情况
print(f"\n📅 年度销售情况:")
for year, group in trade_df.groupby('year'):
year_sales = group['buy_mount'].sum()
year_orders = group.shape[0]
year_users = group['user_id'].nunique()
print(f" {year}年:销量 {year_sales:,} 件,订单 {year_orders:,} 笔,用户 {year_users:,} 人")
# 季度分析
print(f"\n📊 季度分析:")
q1_sales_avg = trade_df[trade_df['quarter'] == 1]['buy_mount'].sum() / 3 # 3年数据
q4_sales_avg = trade_df[trade_df['quarter'] == 4]['buy_mount'].sum() / 3
print(f" 第一季度平均销量:{q1_sales_avg:,.0f} 件")
print(f" 第四季度平均销量:{q4_sales_avg:,.0f} 件")
print(f" 季度差异:{(q4_sales_avg - q1_sales_avg)/q1_sales_avg*100:.1f}%")
# 复购率分析
print(f"\n🔄 复购率分析:")
print(f" 平均月复购率:{monthly_repurchase['当月复购率'].mean():.6f}")
print(f" 最高月复购率:{monthly_repurchase['当月复购率'].max():.6f}")
print(f" 最低月复购率:{monthly_repurchase['当月复购率'].min():.6f}")
# 商品大类分析
print(f"\n🏷️ 商品大类分析:")
top_cats = cat1_sales.sort_values('总销量', ascending=False).head(3)
for idx, row in top_cats.iterrows():
print(f" 大类{row['cat1']}:销量 {row['总销量']:,} 件,用户 {row['总用户数']:,} 人,人均 {row['人均销量']:.2f} 件")
print("\n" + "="*60)
print("✅ 实验分析完成!")
print(f"✅ 已生成11张图表,保存至当前目录")
print("="*60)
实验结果分析
数据处理质量评估
通过系统性的数据清洗,我们成功将原始 29,971 条交易记录处理为 29,800 条高质量的有效订单,数据清洗率为 99.4%。清洗过程排除了购买量异常的订单 29 条,删除了存在缺失值的记录 171 条。
清洗后的数据显示:
- 统计期间:2012 年 7 月 2 日至 2015 年 2 月 5 日
- 总销量:49,452 件商品
- 涉及用户:29,776 名独立用户
- 平均订单购买量:1.66 件 / 单
整体市场趋势分析
从年度销售趋势看,母婴商品市场呈现明显的增长态势:
- 2012 年至 2014 年,年销量从 6,198 件快速增长至 24,349 件
- 三年间规模扩大近三倍,年均复合增长率高达 98.2%
- 表明该市场处于高速发展期
季度分析揭示了显著的季节性波动:
- 第四季度平均销量(5,419 件)显著高于第一季度(3,325 件)
- 差异率达 63.0%,表明下半年尤其是年末是销售旺季
月度趋势进一步细化了波动规律:
- 整体销量走势呈波浪式上升
- 在每年 5 月和 11 月前后均出现明显的销售峰值
- 这些峰值对应 "五一" 促销季与 "双十一" 大促
- 每年春节所在月份及前后,销量均出现明显下滑
第一季度销售下滑归因分析
聚焦 2013 年与 2014 年第一季度的分析显示:
- 销量谷底出现的时间点与当年春节假期高度吻合
- 春节期间销量与用户量同步大幅下降
- 春节效应的影响机制包括:物流停运、消费者注意力转移、返乡潮影响
第四季度销售特征与促销效应分析
2012 年至 2014 年第四季度的分析显示:
- 每年 11 月 11 日 "双十一" 当天,销量均出现极为陡峭的脉冲式峰值
- 用户量也在双十一期间大幅跃升
- 促销活动不仅激发了老用户的购买力,也成功吸引了大量新用户
用户复购行为分析
复购率分析结果显示:
- 整体复购率水平极低,平均仅为 0.000058(即 0.0058%)
- 最高不超过 0.000714(0.0714%)
- 复购行为零星出现,未形成明显的连续月份或稳定趋势
- 不同商品大类的复购率均处于相近的极低水平
商品销售结构深度解析
商品大类分析显示:
- 销量最高的两个大类分别是 "28" 和 "50008168"
- 总销量分别达到 15,864 件和 15,105 件
- 两者合计占总销量的 62.6%,是平台的绝对核心品类
商业启示与建议
营销节奏优化
- 把握关键促销节点:重点关注 5 月、11 月等销售峰值期
- 淡季运营策略:针对春节等淡季制定特殊运营策略
- 促销活动规划:合理安排促销活动,避免过度集中
用户经营策略
- 建立用户生命周期管理体系:通过数据分析识别高潜力用户
- 个性化推荐:针对性地推送个性化的商品推荐与优惠信息
- 会员体系建设:设立会员积分体系与定期的 "老客专享" 活动
商品运营建议
- 巩固核心品类:加强对大类 "28" 和 "50008168" 的运营支持
- 优化潜力品类:对大类 "38" 实施 "爆款打造" 计划
- 品类结构调整:减少滞销子类的库存与展示,将资源向需求更旺盛的子类倾斜
总结
本实验通过对母婴商品销售数据的多维度可视化与分析,系统揭示了市场增长趋势、季节性波动规律、促销活动效应、用户购买习惯及商品品类结构等关键洞察。整体市场处于高速增长通道,但受春节、大型购物节影响显著,销量呈周期性波动。用户复购率极低,表明客户忠诚度培养是未来增长的潜在突破口。
通过数据驱动的持续分析与策略迭代,电商平台可以有效提升销售业绩与市场竞争力。希望本文的分析思路和代码实现能够为从事数据分析的朋友们提供有价值的参考。
更多推荐
所有评论(0)