Python实战:电商用户行为数据分析与RFM模型可视化全流程 这次我们来看一个完整的Python电商用户行为数据分析与可视化实战项目。这个项目不是简单的概念讲解而是从数据清洗、漏斗分析、RFM用户分层到可视化大屏的全流程代码实现。如果你正在准备数据分析相关的毕业设计、简历项目或者面试案例这篇文章提供的源码和思路可以直接复用。项目核心是使用Python处理真实的电商用户行为数据通过Pandas进行数据清洗和转换利用Matplotlib和Seaborn完成可视化最终构建一个能够反映用户价值分层的RFM模型。整个过程不需要复杂的机器学习算法重点在于业务逻辑的理解和数据分析流程的规范化。我们将重点关注如何用代码实现每一个分析步骤以及如何将分析结果转化为直观的图表。本文会带你完成从环境搭建、数据加载、数据清洗、分析建模到可视化输出的全过程。你将获得一套可运行的完整源码并理解每个环节的技术选型和实现细节。无论是数据分析初学者希望有一个实战项目练手还是开发者需要为业务系统集成用户分析模块都能从中找到可参考的内容。1. 核心能力速览能力项说明项目类型电商用户行为数据分析与可视化实战项目技术栈Python, Pandas, NumPy, Matplotlib, Seaborn, Jupyter Notebook核心分析模型RFM模型最近一次消费、消费频率、消费金额主要分析内容用户行为数据清洗、购买漏斗分析、用户价值分层、多维度可视化数据要求结构化的用户交易数据如订单表、用户行为日志输出成果清洗后的数据集、RFM评分表、多种统计分析图表、可视化报告适合场景数据分析学习、毕业设计、简历项目、业务数据分析原型开发硬件门槛普通电脑即可内存建议8G以上用于处理较大数据集启动方式通过Jupyter Notebook或Python脚本按步骤运行2. 适用场景与使用边界这个项目主要适合以下几类人群在校学生需要完成数据分析相关的课程设计、毕业设计项目提供完整的流程和源码便于理解和答辩。求职者希望丰富简历中的数据项目经验RFM模型是电商数据分析中非常经典和实用的案例。初级数据分析师想要通过一个完整项目掌握从原始数据到分析报告的标准工作流。业务人员或产品经理希望通过Python自动化地生成用户分层报告辅助运营决策。项目能解决的核心问题如何将杂乱、原始的电商日志或订单数据清洗成可供分析的结构化数据。如何计算关键的用户行为指标如转化率、复购率等。如何应用RFM模型对用户进行价值分层识别出重要保持用户、重要发展用户、重要挽留用户和一般价值用户。如何将分析结果通过多种图表柱状图、饼图、热力图、雷达图等进行可视化展示。使用边界与注意事项数据敏感性本项目处理的是用户交易和行为数据在实际工作中必须严格遵守数据隐私和安全法规确保数据脱敏仅用于合规的分析目的。模型局限性RFM模型是一个较为宏观的静态分层模型对于预测单个用户未来的具体行为存在局限。它更适合用于群体分析和制定宏观运营策略。业务适配性RFM中R、F、M的阈值划分需要根据具体业务的实际情况如行业特点、消费周期进行调整本文提供的划分方法仅为示例。结果解读数据分析结果需要结合业务知识进行解读避免陷入“唯数据论”。3. 环境准备与前置条件在开始编码之前需要准备好以下环境和数据3.1 软件与工具Python 3.7这是运行数据分析库的基础。建议使用Anaconda发行版它集成了许多科学计算包。Jupyter Notebook / Jupyter Lab非常适合进行交互式数据分析和可视化方便一步步执行和查看结果。也可以通过PyCharm、VSCode等IDE运行.py脚本。必要的Python库我们将通过pip或conda安装以下核心库。# 使用pip安装 pip install pandas numpy matplotlib seaborn scikit-learn # 如果使用Jupyter Notebook pip install jupyter3.2 数据集准备项目需要一个包含用户交易记录的数据集。通常包含以下字段字段名可根据实际数据调整user_id: 用户唯一标识order_id: 订单唯一标识order_date: 订单日期需为日期时间格式product_id: 商品IDcategory: 商品类别amount: 订单金额或商品金额behavior_type: 用户行为类型如pv-浏览 buy-购买 cart-加购 fav-收藏你可以使用公开的电商数据集如阿里天池的“User Behavior Data from Taobao”或使用自己生成的模拟数据。为了便于演示下文会包含一个创建模拟数据的代码块。3.3 目录结构建议创建一个清晰的项目目录便于管理代码、数据和输出结果。ecommerce_analysis_project/ │ ├── data/ # 存放原始数据和清洗后的数据 │ ├── raw/ # 原始数据如.csv文件 │ └── processed/ # 清洗处理后的数据 │ ├── notebooks/ # Jupyter Notebook文件 │ └── rfm_analysis.ipynb │ ├── src/ # Python脚本如果将Notebook转化为.py │ ├── data_cleaning.py │ ├── rfm_calculation.py │ └── visualization.py │ ├── output/ # 生成的图表和报告 │ ├── figures/ # 图片文件.png, .jpg │ └── reports/ # 汇总表格.csv, .xlsx │ └── README.md # 项目说明4. 数据加载与初步探索任何数据分析的第一步都是了解你的数据。我们使用Pandas来加载和查看数据。4.1 加载数据假设我们有一个名为user_behavior.csv的原始数据文件。import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns # 设置中文显示和图表样式 plt.rcParams[font.sans-serif] [SimHei, Arial Unicode MS, DejaVu Sans] plt.rcParams[axes.unicode_minus] False sns.set_style(whitegrid) # 加载数据 df pd.read_csv(./data/raw/user_behavior.csv) print(数据形状:, df.shape) print(\n数据前5行:) print(df.head()) print(\n数据基本信息:) print(df.info()) print(\n数据描述性统计:) print(df.describe())4.2 识别数据问题通过初步查看我们需要检查以下常见问题缺失值df.isnull().sum()重复值df.duplicated().sum()异常值查看金额、日期等字段的分布。数据类型确保order_date是datetime类型。关键字段唯一性检查user_id,order_id是否有重复。5. 数据清洗与预处理原始数据往往不能直接用于分析清洗是关键一步。5.1 处理缺失值与重复值# 删除完全重复的行 df_clean df.drop_duplicates() # 处理缺失值根据业务逻辑这里示例删除‘user_id’或‘amount’为空的记录 df_clean df_clean.dropna(subset[user_id, amount]) # 对于行为类型等字段可以用‘unknown’填充 df_clean[behavior_type] df_clean[behavior_type].fillna(unknown) print(f清洗后数据形状: {df_clean.shape})5.2 转换数据类型与提取特征# 转换日期字段 df_clean[order_date] pd.to_datetime(df_clean[order_date]) # 提取日期特征便于后续按时间维度分析 df_clean[order_year] df_clean[order_date].dt.year df_clean[order_month] df_clean[order_date].dt.month df_clean[order_day] df_clean[order_date].dt.day df_clean[order_dayofweek] df_clean[order_date].dt.dayofweek # 周一为0 df_clean[order_hour] df_clean[order_date].dt.hour print(df_clean[[order_date, order_year, order_month, order_dayofweek]].head())5.3 处理异常值对于金额amount我们可能需要处理负值或极大值。# 假设金额应为正数且我们定义一个合理的上限如99%分位数 amount_q99 df_clean[amount].quantile(0.99) print(f金额的99%分位数是: {amount_q99}) # 筛选出金额在合理范围内的记录或者将异常值截断 df_clean df_clean[(df_clean[amount] 0) (df_clean[amount] amount_q99)] # 另一种方式将大于上限的值赋值为上限值 # df_clean.loc[df_clean[amount] amount_q99, amount] amount_q99清洗完成后将数据保存供后续分析使用。df_clean.to_csv(./data/processed/cleaned_user_behavior.csv, indexFalse)6. 用户行为漏斗分析漏斗分析用于追踪用户从浏览到最终购买的转化过程。我们假设数据中有behavior_type字段记录了“pv”浏览、“cart”加购、“fav”收藏、“buy”购买等行为。6.1 计算各环节用户数# 统计独立用户在不同行为阶段的数量 # 注意一个用户可能有多条同类型行为记录我们按user_id去重 funnel_data {} behavior_stages [pv, cart, fav, buy] # 根据你的数据定义环节 for stage in behavior_stages: # 获取在该阶段有过行为的独立用户数 stage_users df_clean[df_clean[behavior_type] stage][user_id].nunique() funnel_data[stage] stage_users print(f{stage}环节用户数: {stage_users}) # 转换为DataFrame便于绘图 funnel_df pd.DataFrame(list(funnel_data.items()), columns[stage, user_count]) print(funnel_df)6.2 计算转化率与可视化# 计算各环节之间的转化率 funnel_df[conversion_rate] 0.0 for i in range(1, len(funnel_df)): funnel_df.loc[i, conversion_rate] funnel_df.loc[i, user_count] / funnel_df.loc[i-1, user_count] print(funnel_df) # 绘制漏斗图 plt.figure(figsize(10, 6)) # 使用条形图模拟漏斗 bars plt.barh(funnel_df[stage], funnel_df[user_count], colorsns.color_palette(Blues_r, len(funnel_df))) plt.xlabel(独立用户数) plt.title(用户购买行为漏斗分析) # 在条形上添加数量和转化率标签 for i, (bar, count, rate) in enumerate(zip(bars, funnel_df[user_count], funnel_df[conversion_rate])): width bar.get_width() plt.text(width max(funnel_df[user_count])*0.01, bar.get_y() bar.get_height()/2, f{int(count)} ({rate:.1%}) if i0 else f{int(count)}, vacenter) plt.gca().invert_yaxis() # 让第一个环节在最上面 plt.tight_layout() plt.savefig(./output/figures/user_behavior_funnel.png, dpi300) plt.show()通过这个漏斗图可以清晰看到从浏览到购买的转化路径和损耗点帮助定位问题环节。7. RFM模型构建与用户分层RFM模型是衡量客户价值的经典工具。RRecency用户最近一次消费距离分析时点的时间。时间越近价值越高。FFrequency用户在一定时间内的消费频率。频率越高价值越高。MMonetary用户在一定时间内的消费总金额。金额越高价值越高。7.1 计算RFM指标我们需要设定一个分析截止日期snapshot_date通常是数据中最新日期之后的一天。# 设定分析快照日期 snapshot_date df_clean[order_date].max() pd.Timedelta(days1) print(f分析快照日期: {snapshot_date}) # 按用户聚合计算R、F、M rfm df_clean.groupby(user_id).agg({ order_date: lambda x: (snapshot_date - x.max()).days, # Recency: 最近一次消费距今天数 order_id: nunique, # Frequency: 订单数消费次数 amount: sum # Monetary: 消费总金额 }).reset_index() # 重命名列 rfm.columns [user_id, recency, frequency, monetary] print(rfm.head()) print(rfm.describe())7.2 对RFM指标进行评分常用的方法是分位数评分如四分位或自定义阈值。这里使用四分位数将每个指标分为4组1-4分分数越高代表表现越好。注意对于R最近消费天数天数越少越好所以需要反向打分。# 使用qcut进行分位数分组并打分 (4分制) # Recency: 天数越少分数越高反向 rfm[r_score] pd.qcut(rfm[recency], q4, labels[4, 3, 2, 1]) # Frequency和Monetary: 值越大分数越高 rfm[f_score] pd.qcut(rfm[frequency], q4, labels[1, 2, 3, 4]) rfm[m_score] pd.qcut(rfm[monetary], q4, labels[1, 2, 3, 4]) # 将分数转换为整数类型 rfm[r_score] rfm[r_score].astype(int) rfm[f_score] rfm[f_score].astype(int) rfm[m_score] rfm[m_score].astype(int) print(rfm[[user_id, recency, r_score, frequency, f_score, monetary, m_score]].head())7.3 计算RFM总分与用户分层可以将三个分数拼接或者计算加权总分然后进行分层。# 方法1拼接RFM分数如434 rfm[rfm_group] rfm[r_score].astype(str) rfm[f_score].astype(str) rfm[m_score].astype(str) # 方法2计算加权总分假设权重相同 rfm[rfm_score] rfm[r_score] rfm[f_score] rfm[m_score] print(rfm[[user_id, rfm_group, rfm_score]].head())7.4 基于规则的用户价值分层根据业务经验我们可以定义一些规则对用户进行分类。以下是一个常见的八分法示例# 定义分层函数 def rfm_segment(row): if row[r_score] 3 and row[f_score] 3 and row[m_score] 3: return 重要价值用户 elif row[r_score] 3 and row[f_score] 3 and row[m_score] 3: return 重要发展用户 elif row[r_score] 3 and row[f_score] 3 and row[m_score] 3: return 重要保持用户 elif row[r_score] 3 and row[f_score] 3 and row[m_score] 3: return 重要挽留用户 elif row[r_score] 3 and row[f_score] 3 and row[m_score] 3: return 一般价值用户 elif row[r_score] 3 and row[f_score] 3 and row[m_score] 3: return 一般发展用户 elif row[r_score] 3 and row[f_score] 3 and row[m_score] 3: return 一般保持用户 else: return 一般挽留用户 rfm[user_segment] rfm.apply(rfm_segment, axis1) # 查看分层结果分布 segment_distribution rfm[user_segment].value_counts().sort_values(ascendingFalse) print(segment_distribution)8. 数据分析可视化将清洗后的数据和分析结果通过图表展示是数据分析报告的关键。8.1 用户价值分层分布图# 用户分层分布饼图/柱状图 plt.figure(figsize(12, 6)) # 柱状图 ax1 plt.subplot(1, 2, 1) segment_distribution.plot(kindbar, axax1, colorsteelblue) ax1.set_title(用户价值分层分布柱状图) ax1.set_xlabel(用户分层) ax1.set_ylabel(用户数) plt.xticks(rotation45, haright) # 饼图 ax2 plt.subplot(1, 2, 2) colors sns.color_palette(pastel)[0:len(segment_distribution)] wedges, texts, autotexts ax2.pie(segment_distribution.values, labelssegment_distribution.index, autopct%1.1f%%, colorscolors, startangle90) ax2.set_title(用户价值分层分布饼图) # 美化饼图文本 for autotext in autotexts: autotext.set_color(white) autotext.set_fontweight(bold) plt.tight_layout() plt.savefig(./output/figures/user_segment_distribution.png, dpi300) plt.show()8.2 RFM指标分布直方图# 绘制R、F、M三个指标的分布 fig, axes plt.subplots(1, 3, figsize(15, 4)) metrics [recency, frequency, monetary] titles [最近消费天数分布, 消费频率分布, 消费金额分布] for idx, (metric, title) in enumerate(zip(metrics, titles)): ax axes[idx] # 使用Seaborn的histplot可以显示密度曲线 sns.histplot(rfm[metric], kdeTrue, axax, bins30, colorskyblue) ax.set_title(title) ax.set_xlabel(metric) ax.set_ylabel(用户数) plt.tight_layout() plt.savefig(./output/figures/rfm_distribution.png, dpi300) plt.show()8.3 用户分层与RFM均值热力图查看不同分层用户的R、F、M平均值。# 计算各分层的RFM平均值 segment_rfm_mean rfm.groupby(user_segment)[[recency, frequency, monetary]].mean().round(2) print(segment_rfm_mean) # 绘制热力图 plt.figure(figsize(10, 8)) sns.heatmap(segment_rfm_mean, annotTrue, fmtg, cmapYlOrRd, linewidths.5) plt.title(不同用户分层的RFM指标平均值热力图) plt.tight_layout() plt.savefig(./output/figures/segment_rfm_heatmap.png, dpi300) plt.show()8.4 消费趋势时间序列图分析每月或每周的消费总额和订单数趋势。# 按月份聚合消费数据 df_clean[order_year_month] df_clean[order_date].dt.to_period(M) monthly_sales df_clean.groupby(order_year_month).agg({ amount: sum, order_id: nunique, user_id: nunique }).reset_index() monthly_sales[order_year_month] monthly_sales[order_year_month].astype(str) # 转换为字符串便于绘图 fig, axes plt.subplots(2, 1, figsize(14, 10)) # 月度消费金额趋势 axes[0].plot(monthly_sales[order_year_month], monthly_sales[amount], markero, colorgreen, linewidth2) axes[0].set_title(月度消费总金额趋势) axes[0].set_xlabel(年月) axes[0].set_ylabel(消费金额) axes[0].tick_params(axisx, rotation45) axes[0].grid(True, linestyle--, alpha0.7) # 月度订单数与消费用户数趋势双Y轴 ax2 axes[1] line1 ax2.plot(monthly_sales[order_year_month], monthly_sales[order_id], markers, colorblue, label订单数) ax2.set_xlabel(年月) ax2.set_ylabel(订单数, colorblue) ax2.tick_params(axisy, labelcolorblue) ax2.tick_params(axisx, rotation45) ax3 ax2.twinx() line2 ax3.plot(monthly_sales[order_year_month], monthly_sales[user_id], marker^, colorred, label消费用户数) ax3.set_ylabel(消费用户数, colorred) ax3.tick_params(axisy, labelcolorred) # 合并图例 lines line1 line2 labels [l.get_label() for l in lines] ax2.legend(lines, labels, locupper left) axes[1].set_title(月度订单数与消费用户数趋势) axes[1].grid(True, linestyle--, alpha0.7) plt.tight_layout() plt.savefig(./output/figures/monthly_sales_trend.png, dpi300) plt.show()9. 结果输出与报告生成将关键的分析结果保存为文件便于生成报告或集成到其他系统。9.1 保存RFM评分与分层结果# 保存详细的RFM评分表 rfm.to_csv(./output/reports/rfm_score_card.csv, indexFalse) print(RFM评分表已保存。) # 保存用户分层统计摘要 segment_summary rfm[user_segment].value_counts().reset_index() segment_summary.columns [user_segment, user_count] segment_summary[percentage] (segment_summary[user_count] / segment_summary[user_count].sum() * 100).round(2) segment_summary.to_csv(./output/reports/user_segment_summary.csv, indexFalse) print(用户分层统计摘要已保存。)9.2 生成简单的文本分析报告# 生成一个简单的文本报告 report_lines [] report_lines.append(*50) report_lines.append(电商用户行为数据分析报告) report_lines.append(*50) report_lines.append(f分析日期: {pd.Timestamp.now().strftime(%Y-%m-%d %H:%M:%S)}) report_lines.append(f分析用户总数: {rfm.shape[0]}) report_lines.append(f数据时间范围: {df_clean[order_date].min().date()} 至 {df_clean[order_date].max().date()}) report_lines.append(-*50) report_lines.append(用户价值分层结果:) for segment, count in segment_distribution.items(): report_lines.append(f {segment}: {count} 人 ({count/rfm.shape[0]*100:.1f}%)) report_lines.append(-*50) top_segment segment_distribution.index[0] report_lines.append(f核心用户群体: 【{top_segment}】) report_lines.append(*50) report_text \n.join(report_lines) print(report_text) # 将报告保存为文本文件 with open(./output/reports/analysis_summary.txt, w, encodingutf-8) as f: f.write(report_text)10. 项目总结与扩展方向通过以上步骤我们完成了一个从原始数据到可视化报告的完整电商用户行为分析项目。核心流程包括数据清洗、漏斗分析、RFM建模和可视化展示。这套代码和流程可以直接作为毕业设计或面试项目的骨架。最值得尝试的几点数据清洗的完整性真实数据往往比示例复杂尝试处理更多样的数据问题如地址信息解析、商品类目映射能极大提升实战能力。RFM阈值的动态调整不要固守四分位法。尝试根据业务实际如“高价值用户”的金额标准或聚类算法如K-Means来自动划分R、F、M的阈值使分层更贴合业务。可视化大屏集成可以将多个关键图表如漏斗图、分层分布图、趋势图、热力图布局在一个仪表盘中使用Plotly Dash或Streamlit库构建交互式可视化大屏这会让项目展示效果更上一层楼。最容易踩的坑日期格式错误pd.to_datetime转换时注意原始数据的格式否则会导致大量NaT非时间值。数据重复计算在计算F频率时务必明确是按订单数(order_id)还是按交易次数计算避免因退款订单等造成重复。内存不足如果原始数据量极大千万级以上直接使用Pandas可能内存溢出。可以尝试分块读取(chunksize)、使用Dask库或连接数据库直接进行聚合查询。图表美化Matplotlib的默认样式比较基础多花时间学习Seaborn或调整Matplotlib参数颜色、字体、布局能让你的报告更专业。下一步扩展方向结合更多模型在RFM基础上可以尝试聚类分析如K-Means进行无监督用户分群与RFM结果相互验证。预测分析利用历史RFM数据构建分类模型如逻辑回归、XGBoost预测用户下次是否会购买或流失。个性化推荐基于用户行为数据浏览、购买实现一个简单的协同过滤商品推荐原型。自动化与部署将整个分析流程脚本化使用cronLinux或Task SchedulerWindows定期自动运行并通过邮件发送分析报告。这个项目提供了数据分析的完整闭环。建议你用自己的数据或寻找更复杂的公开数据集运行一遍在解决实际错误的过程中你的数据分析能力会得到真正的巩固。