【Python实践案例】电商平台数据分析和挖掘 -用户行为分析
我们用 UserAnalyticsData
这个“乐高工厂”一次性生成 4 组核心指标:
维度 | 积木块 | 一句话卖点 |
---|---|---|
设备分布 | Mobile 45% / Desktop 30% / Tablet 20% | 一眼看清“移动端优先”是不是伪命题 |
小时/周活跃度 | 7×24 热力图 | 工作日 9-18 点才是黄金 9 小时 |
全年日历 | 365 天日活 | 周末 vs 工作日,谁才是真高活 |
转化漏斗 | Homepage → Success 6 级流失 | 购物车到支付不到 83%,钱袋子破洞 |
代码只有 60 行,却像 4 条高速公路,把数据直接开到图表门口。
analytics_data = UserAnalyticsData(seed=42)
环形图:掏空中心,留白暗示“其他”永远只是配角。
热力图:sns.heatmap
直接标数字,色块深浅=流量高低,0 思考成本。
年历图:用 calmap.yearplot
把 365 天压成一张“二维码”,周末红成一片。
漏斗图:不用第三方库,纯手工 matplotlib.patches.Rectangle
详细案例:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import calmap
import matplotlib.patches as patches
from datetime import datetime, timedelta
class UserAnalyticsData:
def __init__(self, seed=42):
np.random.seed(seed)
self.generate_all_data()
def generate_device_data(self):
"""生成设备使用分布数据"""
self.devices = ['Mobile', 'Desktop', 'Tablet', 'Other']
self.device_values = [45, 30, 20, 5]
def generate_hourly_activity(self):
"""生成每小时活跃度数据"""
self.hours = range(24)
self.days = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
# 模拟工作时间段(9-18点)活跃度较高的情况
base_activity = np.random.randint(10, 30, size=(7, 24))
work_hours_boost = np.zeros((7, 24))
work_hours_boost[:, 9:18] = np.random.randint(30, 70, size=(7, 9))
self.activity_data = (base_activity + work_hours_boost).astype(int)
def generate_yearly_activity(self):
"""生成全年活跃度数据"""
self.dates = pd.date_range('2024-01-01', '2024-12-31')
base_activity = np.random.randint(50, 100, len(self.dates))
# 模拟周末活跃度较高的情况
weekend_mask = self.dates.weekday.isin([5, 6])
weekend_boost = np.where(weekend_mask, np.random.randint(50, 100, len(self.dates)), 0)
self.daily_activity = pd.Series(base_activity + weekend_boost, index=self.dates)
def generate_user_flow(self):
"""生成用户流转数据"""
self.stages = ['Homepage', 'Category', 'Product', 'Cart', 'Payment', 'Success']
# 模拟真实的转化漏斗
initial_users = 100
conversion_rates = [0.8, 0.5, 0.75, 0.83] # 各阶段转化率
self.flow_values = [initial_users]
current_users = initial_users
for rate in conversion_rates:
current_users = int(current_users * rate)
self.flow_values.append(current_users)
def generate_all_data(self):
"""生成所有需要的数据"""
self.generate_device_data()
self.generate_hourly_activity()
self.generate_yearly_activity()
self.generate_user_flow()
class UserAnalyticsVisualizer:
def __init__(self, data):
self.data = data
def setup_plot_style(self):
"""设置绘图样式"""
plt.figure(figsize=(20, 15))
plt.rcParams['figure.facecolor'] = 'white'
plt.rcParams['axes.facecolor'] = 'white'
plt.rcParams['grid.color'] = 'gray'
plt.rcParams['grid.linestyle'] = '--'
plt.rcParams['font.sans-serif'] = ['SimHei'] # 使用黑体
plt.rcParams['axes.unicode_minus'] = False # 处理负号显示
def plot_device_distribution(self, ax):
"""绘制设备分布环形图"""
plt.sca(ax)
plt.pie(self.data.device_values, labels=self.data.devices,
autopct='%1.1f%%', pctdistance=0.85,
wedgeprops=dict(width=0.5))
plt.title('设备分布环形图')
def plot_activity_heatmap(self, ax):
"""绘制活跃度热力图"""
plt.sca(ax)
sns.heatmap(self.data.activity_data,
xticklabels=self.data.hours,
yticklabels=self.data.days,
cmap='YlOrRd',
annot=True,
fmt='d') # 使用'd'因为数据已经转换为整数
plt.title('活跃度热力图')
def plot_yearly_calendar(self, ax):
"""绘制年度日历图"""
plt.sca(ax)
calmap.yearplot(self.data.daily_activity,
year=2024,
cmap='YlOrRd',
fillcolor='lightgrey',
daylabels='MTWTFSS')
plt.title('年度日历图 (2024)')
def draw_flow(self, ax, x, y, width, height, color):
"""绘制流动效果辅助函数"""
rect = patches.Rectangle((x, y), width, height,
facecolor=color, alpha=0.6)
ax.add_patch(rect)
def plot_user_flow(self, ax):
"""绘制用户流转图"""
plt.sca(ax)
colors = plt.cm.Oranges(np.linspace(0.3, 0.9, len(self.data.stages)))
y_positions = np.linspace(0.2, 0.8, len(self.data.stages))
for i in range(len(self.data.flow_values)):
self.draw_flow(ax, i*0.15, y_positions[i], 0.1,
self.data.flow_values[i]/200, colors[i])
plt.text(i*0.15-0.02, y_positions[i],
self.data.stages[i], rotation=45)
if i < len(self.data.flow_values):
plt.text(i*0.15+0.05, y_positions[i]+self.data.flow_values[i]/400,
str(self.data.flow_values[i]))
ax.set_xlim(-0.1, 1)
ax.set_ylim(0, 1)
ax.axis('off')
plt.title('用户流转图')
def create_visualization(self):
"""创建所有可视化图表"""
self.setup_plot_style()
# 创建子图
ax1 = plt.subplot(221)
ax2 = plt.subplot(222)
ax3 = plt.subplot(223)
ax4 = plt.subplot(224)
# 绘制各个图表
self.plot_device_distribution(ax1)
self.plot_activity_heatmap(ax2)
self.plot_yearly_calendar(ax3)
self.plot_user_flow(ax4)
plt.tight_layout()
plt.show()
def generate_report(self):
"""生成数据分析报告"""
print("\n数据分析报告:")
print("1. 设备使用分布:")
print(f" - 移动端用户占比最高,达到{self.data.device_values[0]}%")
print(f" - 桌面端次之,占{self.data.device_values[1]}%")
print("\n2. 用户活跃时间分析:")
print(" - 工作日活跃度高于周末")
print(" - 高峰时段集中在9:00-18:00")
print("\n3. 全年活跃度分析:")
print(f" - 平均日活跃用户数: {self.data.daily_activity.mean():.0f}")
print(f" - 最高日活跃用户数: {self.data.daily_activity.max()}")
print("\n4. 用户行为流转:")
conversion_rate = (self.data.flow_values[-1] / self.data.flow_values[0]) * 100
cart_to_payment = (self.data.flow_values[-2] / self.data.flow_values[-3]) * 100
print(f" - 从首页到成功支付的转化率约为{conversion_rate:.1f}%")
print(f" - 购物车到支付环节的转化率为{cart_to_payment:.1f}%")
# 使用示例
if __name__ == "__main__":
# 生成数据
analytics_data = UserAnalyticsData(seed=42)
# 创建可视化器并展示结果
visualizer = UserAnalyticsVisualizer(analytics_data)
visualizer.create_visualization()
visualizer.generate_report()