从运营后台拉出来几十万条订单数据,摆在面前却不知道从哪里下手——这是很多做电商数据分析的朋友都遇到过的真实场景。数据量不小、字段不少、业务方催着要结论,但你心里清楚,光给几张报表没什么用,业务想看的其实是“用户到底怎么花钱、哪些人值得重点维护、哪些人正在流失”。这篇文章我想分享一次完整的实践:基于Python对电商场景下的用户消费行为数据进行全流程分析,从数据清洗到RFM分层再到策略映射,把整套从“数据”到“业务动作”的链路捋清楚。整个项目我定位为一次用户消费行为分析的单人实战,数据来自某电商平台的脱敏订单记录,规模在十万条以上。适合正在做数据分析、商业分析或在电商公司做运营策略的人参考,也适合想系统掌握pandas数据处理和RFM模型落地的新手。读完之后你会拿到一套可以直接迁移到你自己业务数据上的分析框架、Python代码思路与一堆我用真实数据分析时填过的坑。1. 整体分析思路:从一堆订单到一张用户画像1.1 我们到底想从数据里挖什么电商场景的用户行为分析,核心就四个问题:谁在买、买什么、怎么买、买完还来不来。这四个问题对应着不同的数据视角。“谁在买”要看用户基本特征和消费能力,比如新客占比、高价值用户是谁;“买什么”要落到商品和类目维度,看什么品类贡献主要营收;“怎么买”看支付渠道、下单时段、购买频率;“买完还来不来”则必须拉出时间序列,算复购率、留存率、流失节奏。很多分析项目之所以做着做着就变成“报表生成器”,是因为没有先把这四类问题定义清楚,导致分析维度越来越散,最后产出一堆图表但没有指向性。我在做这次分析前,先给自己定了一个目标:不追求图表多,而是要产出“用户分层结论 + 对应运营建议”,让业务方拿走就能用。1.2 为什么选Python这套技术栈做电商用户消费行为分析,可选工具很多:Excel、SQL、BI工具、Python。我最终选了Python,原因是这个场景下数据量已经到了Excel处理起来会卡顿的级别,SQL能查到聚合结果但做复杂清洗和建模比较绕,BI工具适合固定看板不适合探索性分析。Python的好处是pandas处理表格数据非常顺手,一行groupby就能完成聚合;matplotlib和seaborn出图快,能把分层结果、留存曲线可视化出来;后续如果要接聚类、预测模型,sklearn也在同一个生态里,不用换工具。pandas:数据处理、透视、聚合 matplotlib + seaborn:可视化 datetime:时间字段处理 numpy:数值计算这套组合足够覆盖“清洗—探索—建模—出图—结论”的完整链路。对于十万行级别的订单数据,pandas的表现完全是轻松应对。1.3 分析框架:RFM模型与漏斗思维的合并我在这次项目中用了经典的用户价值分析框架——RFM模型。R(Recency)代表最近一次消费距今的间隔,F(Frequency)代表消费频率,M(Monetary)代表消费金额。这三个维度能从不同侧面刻画一个用户的消费活跃度、忠诚度和消费力。选择RFM而不是直接上机器学习分类,原因是这个项目没有标注好的“高价值用户”样本,而且RFM的可解释性极强:业务方看到“最近没来买、以前买得频繁、金额很高”这样的用户画像,立刻就能知道这是沉睡高价值用户,应该用专属优惠券触达。如果用一个黑盒聚类模型,业务方很难理解为什么某个用户被分到某一类,落地阻力会大很多。除了RFM,我还结合了漏斗思维:从“首次消费→二次复购→多次复购→流失”这条路径去看用户的留存情况,能发现用户是在哪个环节流失最严重。比如很多平台的问题是首购转化不错但复购率始终上不去,说明问题出在商品体验或复购触达环节,这时候做RFM分层也要把复购特征单独拿出来看。2. 数据准备:拿到原始数据之后先别急着跑模型2.1 原始数据长什么样我这次用的模拟数据来自某电商平台的脱敏用户订单记录,一共约12万条,时间跨度从2023年1月到2024年5月。字段结构如下表:字段名类型含义user_id字符串脱敏用户IDorder_id字符串订单编号order_date字符串下单日期category字符串商品类目product_name字符串商品名称amount浮点型订单金额(元)quantity整型购买数量payment_method字符串支付方式user_register_date字符串用户注册日期看起来结构很清晰,但真实数据永远不会这么干净——日期有格式不统一、金额字段有带货币符号的脏值、同一个用户ID出现大小写不一致的情况等等。这些都是实际场景里非常典型的问题。2.2 数据清洗的关键动作与细节拿到数据第一件事永远是检查数据结构,不是上来就画图。我的清洗步骤大概是这样的。去重。先检查order_id是否重复。有些订单会因为系统重试产生重复记录,直接按order_id去重。缺失值处理。重点看amount、quantity、order_date这三列。如果订单金额缺失,通常意味着订单状态异常或数据采集bug,这类记录不能直接用来分析金额指标。格式统一。order_date字段里混用了“2023/1/15”和“2023-01-15”两种格式,需要统一转成datetime类型;amount字段有部分值带“¥”符号,要清理成纯数值。异常值排查。包括金额小于0的退款/异常单、数量为0或负数的异常记录、购买日期早于注册日期的逻辑错误等。提示:不建议一上来就dropna( )。很多时候缺失值本身就有业务含义,比如某些订单没有支付方式可能是“未支付先下单”的流程设计。先理解业务再决定处理方法。2.3 特征工程:从0到1构建用户级特征表原始数据是订单级的,一行代表一次购买行为。但之后要做RFM分析和用户画像,分析单位必须是“用户”,所以要把订单级数据聚合到用户级。这一步是整个项目里最关键的数据处理环节。我建立了一张用户特征表,包含这些核心特征:用户ID首次下单日期和最后一次下单日期总下单次数总消费金额平均客单价购买类目数量偏好类目(按消费金额占比最高者)偏好支付方式常用下单时段注册到首购的间隔天数这些特征的构建逻辑都不复杂,但每一条背后都有业务意义。比如“注册到首购的间隔天数”能看出新用户转化效率,“购买类目数量”能看出用户是垂直型还是广撒网型消费,“偏好支付方式”则指导后续优惠券发放渠道。实操心得:构建用户特征表时不要只保留一个日期的聚合结果,首次消费日期和末次消费日期要分开存,后面做新老客分析、生命周期分析都要用。3. 分析方法与核心指标拆解3.1 用户价值分层:RFM落地实操RFM落地时,首先需要解决“怎么打分”的问题。最常见的是五分位法:对每一位用户的R、F、M取值,在全体用户中按分位数给1到5分,然后用不同维度分数组合出不同用户类型。R值:最近一次消费距今的天数,越小越好,所以分数越高代表越活跃F值:消费次数,越高越好M值:累计消费金额,越高越好三个维度分别打分后,我用“高于均值/低于均值”的方式将用户分成8类。下表是分群结果和运营策略的对应关系。用户类型RFM运营策略方向高价值活跃用户高高高VIP维护、新品优先触达高价值沉睡用户低高高重点召回、专属优惠高价值新用户高低高引导复购、关联推荐高价值流失用户低低高流失预警、大额券召回中低价值活跃用户高高低提升客单价、升级推荐中低价值沉睡用户低高低唤醒活动、推送促销新用户高低低首单转化、逐步培养低价值流失用户低低低低投入触达、节省预算这个8类分群是RFM最经典的应用方式,特别适合给运营做第一版用户分群。实际执行中我没有直接按均值硬切,而是结合了业务经验调整阈值,比如沉睡的定义是超过60天未购买,而不是低于均值就算R低。3.2 复购与留存分析中的计算细节RFM能回答用户当下处于什么状态,但要回答“用户是怎么一步步变成这样的”,必须看复购和留存。复购率我按“在观察窗口内下单超过1次的用户 / 当期首购用户数”来算,而不是简单算“所有订单中复购订单的占比”,后者会被老用户的高频购买严重干扰,导致新用户复购问题被掩盖。留存率则用同期群分析的方法来算:将用户按首次消费月份分组,然后统计他们在下一个月、下两个月之后是否再次消费。这样可以清楚地看到不同时期获取的新用户,在后续几个月的留存曲线对比。举一个我在项目中算出来的典型结论:某个月的拉新用户量很大,但次月留存率比上一个月份获取的用户低了将近8个百分点。单独看整体留存率曲线只会觉得“留存一直在降”,但拆成同期群之后就发现是渠道质量问题而不是产品问题。这就是分析维度要拆细的价值所在。3.3 消费行为偏好与商品关联视角除了用户分层,消费行为分析还要覆盖“买什么”的维度。这里我主要看了三块内容。类目消费结构。把每个用户的订单金额按类目拆分,算每个类目的用户渗透率和金额贡献占比。有些类目渗透率高但客单价低,是引流型商品;有些渗透率低但客单价高,是利润型商品。两者的运营策略完全不同。时段偏好。通过对order_date中的小时字段做提取,可以画出用户下单时段分布。有的品类是典型的晚上下单高峰,有的品类则是上午通勤时段高发。这直接决定了推送消息的最佳时机。组合购买意向。虽然没有做复杂的关联规则挖掘,但通过简单统计“购买了A类目的用户中,有多少比例也购买了B类目”,能发现不少交叉销售的线索。比如在某项目中,购买某类家居商品的人有很高的概率同时买某类收纳商品,这类组合可以直接做成商品推荐位。4. 实操过程与核心环节实现4.1 清洗阶段的Python代码与运行效果整个清洗流程我封装成了几个函数,保持每一步可复现。import pandas as pd import numpy as np from datetime import datetime df = pd.read_csv('ecommerce_orders.csv', parse_dates=['order_date']) # 1. 订单去重 df = df.drop_duplicates(subset=['order_id'], keep='first') # 2. 清除金额字段中的货币符号并转数值 df['amount'] = df['amount'].astype(str).str.replace('¥', '').str.replace(',', '').astype(float) # 3. 过滤异常数据:金额大于0,数量大于0,日期逻辑正常 df = df[(df['amount'] > 0) & (df['quantity'] > 0)] df = df[df['order_date'] >= df['user_register_date']] # 4. 提取下单小时、月份、星期等时间特征 df['order_hour'] = df['order_date'].dt.hour df['order_month'] = df['order_date'].dt.to_period('M') df['order_weekday'] = df['order_date'].dt.weekday print(f"清洗后剩余数据量:{len(df)}") print(f"覆盖用户数:{df['user_id'].nunique()}")运行之后,原始12万条数据清洗后剩11万条左右,剔除掉约6%的异常和重复记录,覆盖用户数从4.5万降到4.3万。这个比例在电商数据里是非常正常的,如果清洗后数据几乎没少,反而要怀疑是不是没把问题查出来。4.2 RFM计算与可视化输出RFM计算的核心代码如下。# 设定观察截止日期(模拟数据最后一天) snapshot_date = df['order_date'].max() # 用户级聚合 rfm = df.groupby('user_id').agg( recency_days=('order_date', lambda x: (snapshot_date - x.max()).days), frequency=('order_id', 'nunique'), monetary=('amount', 'sum') ).reset_index() # 分位数打分 rfm['R_score'] = pd.qcut(rfm['recency_days'], 5, labels=[5, 4, 3, 2, 1]) rfm['F_score'] = pd.qcut(rfm['frequency'].rank(method='first'), 5, labels=[1, 2, 3, 4, 5]) rfm['M_score'] = pd.qcut(rfm['monetary'].rank(method='first'), 5, labels=[1, 2, 3, 4, 5]) # 分档:高于均值算1,低于均值算0 rfm['R_flag'] = np.where(rfm['R_score'].astype(int) > rfm['R_score'].astype(int).mean(), 1, 0) rfm['F_flag'] = np.where(rfm['F_score'].astype(int) > rfm['F_score'].astype(int).mean(), 1, 0) rfm['M_flag'] = np.where(rfm['M_score'].astype(int) > rfm['M_score'].astype(int).mean(), 1, 0)这里有一个容易被坑的点:pd.qcut对重复值会报错,尤其是F值(下单次数)这个字段分布非常偏,大量用户的值都是1。我的处理方式是用rank(method='first')把重复值先变成序号再分位,这样就能正常切分了。可视化部分我用seaborn画了用户分层占比和消费金额贡献度对比图。import matplotlib.pyplot as plt import seaborn as sns # 各分层用户数量占比 rfm['用户类型'] = rfm.apply(lambda r: type_map[(r['R_flag'], r['F_flag'], r['M_flag'])], axis=1) type_count = rfm['用户类型'].value_counts() plt.figure(figsize=(10, 6)) sns.barplot(x=type_count.index, y=type_count.values) plt.title('用户类型分布') plt.xticks(rotation=45) plt.show() # 各分层消费金额占比 type_money = rfm.groupby('用户类型')['monetary'].sum() / rfm['monetary'].sum() * 100画出来的结果很有代表性:占用户数不到15%的高价值活跃用户,贡献了将近45%的消费金额;而占用户数超过35%的低价值流失用户,只贡献了不到8%的金额。这类图给业务方看的时候冲击力很强,比念数字管用得多。4.3 将结论落地成运营策略分析的最终输出不是图表而是策略。我把每个用户分层的特征、典型画像和运营建议整理成了一张策略表,并标注了建议的触达频次和渠道偏好。用户类型典型画像建议策略触达方式预计价值高价值活跃近30天有购买,年消费10次以上,客单价高持续维护,优先推送高毛利新品短信+专属客服巩固核心收入高价值沉睡60天以上未购买,历史消费高大额回归礼包、会员积分提醒人工外呼+优惠券高概率召回高价值流失90天以上未购买,历史消费高最后触达一次,超预算则放弃短信+微信止损新用户首次购买30天内7天内复购券,关联推荐高频类目App push拉高首月复购率低价值沉睡低频低额不投入或仅大促触达大促邮件低成本唤醒实操心得:RFM分层不是一次性工作。用户的状态一直在变,分析频率至少要按月滚动。我在项目结束后将这套计算逻辑封装成月度定时任务,月底自动跑一遍,输出新的分层结果给运营侧使用。如果只做一次性分析,价值的衰减会非常快。5. 常见问题与排查技巧实录5.1 数据清洗阶段三个高频坑第一个坑:删除包含缺失值的整行记录时,把有价值的用户信息也删掉了。比如某条订单记录缺失了支付方式字段,但金额和用户ID都正常,如果直接删掉,这个用户的总金额就会少一单。我的处理方式是区分处理:核心字段(金额、时间、用户ID)缺失不可原谅,要删除;非核心字段(支付方式、商品描述)缺失,用“未知”填充或单独归类。第二个坑:订单金额为负数的记录,不全是脏数据。负金额可能是退款订单,也可能是自动核销的优惠补偿。如果统一过滤掉,会低估退款率,影响后续对高价值流失用户的判断。我建议先把负金额订单单独提取出来看业务含义,再做决定。第三个坑:groupby聚合后索引混乱导致join出错。这是新手最容易踩的pandas问题。在构建用户特征表时,如果做完groupby直接和其他表做合并,没有reset_index,会把user_id变成索引而不是列,后面一旦做merge就全部错位。我的习惯是聚合之后立刻reset_index(drop=False),先把索引还原成普通列。5.2 指标计算口径不一致问题分析过程中最大的口径雷区是“用户数”的定义。是统计注册用户数、首购用户数、还是有购买行为的活跃用户数?不同口径算出来的转化率可以差好几倍。我在项目中明确了所有关键指标的口径定义:新用户 = 在某时间段内完成首次下单的用户活跃用户 = 在观察周期内至少有1笔有效订单的用户留存用户 = 在某期首次消费后的第N个周期内再次消费的用户复购用户 = 在观察周期内下单次数大于1的用户每个口径定义都写进了分析文档,并在交付时单独做了一页“指标口径说明”,避免业务方对数字产生歧义。5.3 可视化呈现的避坑要点分析做得再好,图出得乱七八糟也是白费。我在出图阶段总结了几个原则。排序不要默认字母序。比如分层的用户类型如果按字符串排序,“中价值”会出现在“高价值”前面,看起来很不直观。手动指定分类顺序再画图,信息传达效率会高很多。占比图一定要显示具体数字。饼图或堆叠柱状图如果没有数值标签,业务方只能大概看出谁多谁少,看不出“高价值用户只占12%但贡献了40%金额”这种关键结论,分析的说服力就打了折扣。同期群热力图用颜色梯度而不是单一色。我在展示留存率变化时用seaborn的热力图,纵轴是首购月份、横轴是消费周期,色块越深代表留存率越高,一眼就能看出哪个月获取的用户质量更差。避坑建议:不要把结论只写在图里。图表旁边用一句加粗文字写出核心洞察,比如“3月新增用户次月留存率较均值低8个百分点”。很多看报告的人只会扫结论,不会自己从图里提炼信息。6. 这个分析后续还能扩展什么这次项目做到用户分层和策略映射,已经能覆盖大部分日常运营需求,但消费行为分析的方向远不止于此。我在做完首版之后,已经在规划三个扩展方向。第一是用户生命周期价值预测。当前分析是从历史数据看用户已实现的价值,如果能结合用户消费频次、客单价和留存概率做CLV预测,就可以判断一个用户的长期价值是否值得更高的获客成本。第二是流失预警模型。RFM分层能告诉我们哪些用户已经流失或沉睡,但属于事后识别。更有效的做法是用用户近期的行为序列特征训练一个分类模型,在用户流失概率开始升高时就发出预警信号,让运营尽早干预。第三是商品关联推荐。我在这次分析里只做了简单的交叉购买占比统计,下一步可以引入关联规则算法,挖掘品类和商品间的深层关联,直接指导推荐策略。如果团队积累的数据足够多、埋点足够完整,还可以把用户浏览、点击、加购等行为数据也纳入分析,从“订单消费行为”扩展到“完整消费意图链路”,那能看到的东西就更多了。做这种分析项目,我最深的体会是:技术本身并不复杂,pandas不会比Excel难多少,RFM也不是什么高深模型,真正的分水岭在于你有没有把业务问题翻译成数据问题、再把数据结论翻译回业务语言。第一次做的时候我花了很多时间在调颜色、调图表样式上,后来发现业务方根本不在乎这些,他们在乎的是“哪些用户要重点跟、哪些用户可以不跟了、为什么”。把这个想明白,项目就成功了一大半。最后再分享一个小技巧:做完整套分析后,找一个对业务很熟但完全不懂数据的同事,把结论讲给他听,如果他能听懂并且能提问题,那这份分析才算真正接地气了。
从运营后台拉出来几十万条订单数据,摆在面前却不知道从哪里下手——这是很多做电商数据分析的朋友都遇到过的真实场景。数据量不小、字段不少、业务方催着要结论,但你心里清楚,光给几张报表没什么用,业务想看的其实是“用户到底怎么花钱、哪些人值得重点维护、哪些人正在流失”。这篇文章我想分享一次完整的实践:基于Python对电商场景下的用户消费行为数据进行全流程分析,从数据清洗到RFM分层再到策略映射,把整套从“数据”到“业务动作”的链路捋清楚。整个项目我定位为一次用户消费行为分析的单人实战,数据来自某电商平台的脱敏订单记录,规模在十万条以上。适合正在做数据分析、商业分析或在电商公司做运营策略的人参考,也适合想系统掌握pandas数据处理和RFM模型落地的新手。读完之后你会拿到一套可以直接迁移到你自己业务数据上的分析框架、Python代码思路与一堆我用真实数据分析时填过的坑。1. 整体分析思路:从一堆订单到一张用户画像1.1 我们到底想从数据里挖什么电商场景的用户行为分析,核心就四个问题:谁在买、买什么、怎么买、买完还来不来。这四个问题对应着不同的数据视角。“谁在买”要看用户基本特征和消费能力,比如新客占比、高价值用户是谁;“买什么”要落到商品和类目维度,看什么品类贡献主要营收;“怎么买”看支付渠道、下单时段、购买频率;“买完还来不来”则必须拉出时间序列,算复购率、留存率、流失节奏。很多分析项目之所以做着做着就变成“报表生成器”,是因为没有先把这四类问题定义清楚,导致分析维度越来越散,最后产出一堆图表但没有指向性。我在做这次分析前,先给自己定了一个目标:不追求图表多,而是要产出“用户分层结论 + 对应运营建议”,让业务方拿走就能用。1.2 为什么选Python这套技术栈做电商用户消费行为分析,可选工具很多:Excel、SQL、BI工具、Python。我最终选了Python,原因是这个场景下数据量已经到了Excel处理起来会卡顿的级别,SQL能查到聚合结果但做复杂清洗和建模比较绕,BI工具适合固定看板不适合探索性分析。Python的好处是pandas处理表格数据非常顺手,一行groupby就能完成聚合;matplotlib和seaborn出图快,能把分层结果、留存曲线可视化出来;后续如果要接聚类、预测模型,sklearn也在同一个生态里,不用换工具。pandas:数据处理、透视、聚合 matplotlib + seaborn:可视化 datetime:时间字段处理 numpy:数值计算这套组合足够覆盖“清洗—探索—建模—出图—结论”的完整链路。对于十万行级别的订单数据,pandas的表现完全是轻松应对。1.3 分析框架:RFM模型与漏斗思维的合并我在这次项目中用了经典的用户价值分析框架——RFM模型。R(Recency)代表最近一次消费距今的间隔,F(Frequency)代表消费频率,M(Monetary)代表消费金额。这三个维度能从不同侧面刻画一个用户的消费活跃度、忠诚度和消费力。选择RFM而不是直接上机器学习分类,原因是这个项目没有标注好的“高价值用户”样本,而且RFM的可解释性极强:业务方看到“最近没来买、以前买得频繁、金额很高”这样的用户画像,立刻就能知道这是沉睡高价值用户,应该用专属优惠券触达。如果用一个黑盒聚类模型,业务方很难理解为什么某个用户被分到某一类,落地阻力会大很多。除了RFM,我还结合了漏斗思维:从“首次消费→二次复购→多次复购→流失”这条路径去看用户的留存情况,能发现用户是在哪个环节流失最严重。比如很多平台的问题是首购转化不错但复购率始终上不去,说明问题出在商品体验或复购触达环节,这时候做RFM分层也要把复购特征单独拿出来看。2. 数据准备:拿到原始数据之后先别急着跑模型2.1 原始数据长什么样我这次用的模拟数据来自某电商平台的脱敏用户订单记录,一共约12万条,时间跨度从2023年1月到2024年5月。字段结构如下表:字段名类型含义user_id字符串脱敏用户IDorder_id字符串订单编号order_date字符串下单日期category字符串商品类目product_name字符串商品名称amount浮点型订单金额(元)quantity整型购买数量payment_method字符串支付方式user_register_date字符串用户注册日期看起来结构很清晰,但真实数据永远不会这么干净——日期有格式不统一、金额字段有带货币符号的脏值、同一个用户ID出现大小写不一致的情况等等。这些都是实际场景里非常典型的问题。2.2 数据清洗的关键动作与细节拿到数据第一件事永远是检查数据结构,不是上来就画图。我的清洗步骤大概是这样的。去重。先检查order_id是否重复。有些订单会因为系统重试产生重复记录,直接按order_id去重。缺失值处理。重点看amount、quantity、order_date这三列。如果订单金额缺失,通常意味着订单状态异常或数据采集bug,这类记录不能直接用来分析金额指标。格式统一。order_date字段里混用了“2023/1/15”和“2023-01-15”两种格式,需要统一转成datetime类型;amount字段有部分值带“¥”符号,要清理成纯数值。异常值排查。包括金额小于0的退款/异常单、数量为0或负数的异常记录、购买日期早于注册日期的逻辑错误等。提示:不建议一上来就dropna( )。很多时候缺失值本身就有业务含义,比如某些订单没有支付方式可能是“未支付先下单”的流程设计。先理解业务再决定处理方法。2.3 特征工程:从0到1构建用户级特征表原始数据是订单级的,一行代表一次购买行为。但之后要做RFM分析和用户画像,分析单位必须是“用户”,所以要把订单级数据聚合到用户级。这一步是整个项目里最关键的数据处理环节。我建立了一张用户特征表,包含这些核心特征:用户ID首次下单日期和最后一次下单日期总下单次数总消费金额平均客单价购买类目数量偏好类目(按消费金额占比最高者)偏好支付方式常用下单时段注册到首购的间隔天数这些特征的构建逻辑都不复杂,但每一条背后都有业务意义。比如“注册到首购的间隔天数”能看出新用户转化效率,“购买类目数量”能看出用户是垂直型还是广撒网型消费,“偏好支付方式”则指导后续优惠券发放渠道。实操心得:构建用户特征表时不要只保留一个日期的聚合结果,首次消费日期和末次消费日期要分开存,后面做新老客分析、生命周期分析都要用。3. 分析方法与核心指标拆解3.1 用户价值分层:RFM落地实操RFM落地时,首先需要解决“怎么打分”的问题。最常见的是五分位法:对每一位用户的R、F、M取值,在全体用户中按分位数给1到5分,然后用不同维度分数组合出不同用户类型。R值:最近一次消费距今的天数,越小越好,所以分数越高代表越活跃F值:消费次数,越高越好M值:累计消费金额,越高越好三个维度分别打分后,我用“高于均值/低于均值”的方式将用户分成8类。下表是分群结果和运营策略的对应关系。用户类型RFM运营策略方向高价值活跃用户高高高VIP维护、新品优先触达高价值沉睡用户低高高重点召回、专属优惠高价值新用户高低高引导复购、关联推荐高价值流失用户低低高流失预警、大额券召回中低价值活跃用户高高低提升客单价、升级推荐中低价值沉睡用户低高低唤醒活动、推送促销新用户高低低首单转化、逐步培养低价值流失用户低低低低投入触达、节省预算这个8类分群是RFM最经典的应用方式,特别适合给运营做第一版用户分群。实际执行中我没有直接按均值硬切,而是结合了业务经验调整阈值,比如沉睡的定义是超过60天未购买,而不是低于均值就算R低。3.2 复购与留存分析中的计算细节RFM能回答用户当下处于什么状态,但要回答“用户是怎么一步步变成这样的”,必须看复购和留存。复购率我按“在观察窗口内下单超过1次的用户 / 当期首购用户数”来算,而不是简单算“所有订单中复购订单的占比”,后者会被老用户的高频购买严重干扰,导致新用户复购问题被掩盖。留存率则用同期群分析的方法来算:将用户按首次消费月份分组,然后统计他们在下一个月、下两个月之后是否再次消费。这样可以清楚地看到不同时期获取的新用户,在后续几个月的留存曲线对比。举一个我在项目中算出来的典型结论:某个月的拉新用户量很大,但次月留存率比上一个月份获取的用户低了将近8个百分点。单独看整体留存率曲线只会觉得“留存一直在降”,但拆成同期群之后就发现是渠道质量问题而不是产品问题。这就是分析维度要拆细的价值所在。3.3 消费行为偏好与商品关联视角除了用户分层,消费行为分析还要覆盖“买什么”的维度。这里我主要看了三块内容。类目消费结构。把每个用户的订单金额按类目拆分,算每个类目的用户渗透率和金额贡献占比。有些类目渗透率高但客单价低,是引流型商品;有些渗透率低但客单价高,是利润型商品。两者的运营策略完全不同。时段偏好。通过对order_date中的小时字段做提取,可以画出用户下单时段分布。有的品类是典型的晚上下单高峰,有的品类则是上午通勤时段高发。这直接决定了推送消息的最佳时机。组合购买意向。虽然没有做复杂的关联规则挖掘,但通过简单统计“购买了A类目的用户中,有多少比例也购买了B类目”,能发现不少交叉销售的线索。比如在某项目中,购买某类家居商品的人有很高的概率同时买某类收纳商品,这类组合可以直接做成商品推荐位。4. 实操过程与核心环节实现4.1 清洗阶段的Python代码与运行效果整个清洗流程我封装成了几个函数,保持每一步可复现。import pandas as pd import numpy as np from datetime import datetime df = pd.read_csv('ecommerce_orders.csv', parse_dates=['order_date']) # 1. 订单去重 df = df.drop_duplicates(subset=['order_id'], keep='first') # 2. 清除金额字段中的货币符号并转数值 df['amount'] = df['amount'].astype(str).str.replace('¥', '').str.replace(',', '').astype(float) # 3. 过滤异常数据:金额大于0,数量大于0,日期逻辑正常 df = df[(df['amount'] > 0) & (df['quantity'] > 0)] df = df[df['order_date'] >= df['user_register_date']] # 4. 提取下单小时、月份、星期等时间特征 df['order_hour'] = df['order_date'].dt.hour df['order_month'] = df['order_date'].dt.to_period('M') df['order_weekday'] = df['order_date'].dt.weekday print(f"清洗后剩余数据量:{len(df)}") print(f"覆盖用户数:{df['user_id'].nunique()}")运行之后,原始12万条数据清洗后剩11万条左右,剔除掉约6%的异常和重复记录,覆盖用户数从4.5万降到4.3万。这个比例在电商数据里是非常正常的,如果清洗后数据几乎没少,反而要怀疑是不是没把问题查出来。4.2 RFM计算与可视化输出RFM计算的核心代码如下。# 设定观察截止日期(模拟数据最后一天) snapshot_date = df['order_date'].max() # 用户级聚合 rfm = df.groupby('user_id').agg( recency_days=('order_date', lambda x: (snapshot_date - x.max()).days), frequency=('order_id', 'nunique'), monetary=('amount', 'sum') ).reset_index() # 分位数打分 rfm['R_score'] = pd.qcut(rfm['recency_days'], 5, labels=[5, 4, 3, 2, 1]) rfm['F_score'] = pd.qcut(rfm['frequency'].rank(method='first'), 5, labels=[1, 2, 3, 4, 5]) rfm['M_score'] = pd.qcut(rfm['monetary'].rank(method='first'), 5, labels=[1, 2, 3, 4, 5]) # 分档:高于均值算1,低于均值算0 rfm['R_flag'] = np.where(rfm['R_score'].astype(int) > rfm['R_score'].astype(int).mean(), 1, 0) rfm['F_flag'] = np.where(rfm['F_score'].astype(int) > rfm['F_score'].astype(int).mean(), 1, 0) rfm['M_flag'] = np.where(rfm['M_score'].astype(int) > rfm['M_score'].astype(int).mean(), 1, 0)这里有一个容易被坑的点:pd.qcut对重复值会报错,尤其是F值(下单次数)这个字段分布非常偏,大量用户的值都是1。我的处理方式是用rank(method='first')把重复值先变成序号再分位,这样就能正常切分了。可视化部分我用seaborn画了用户分层占比和消费金额贡献度对比图。import matplotlib.pyplot as plt import seaborn as sns # 各分层用户数量占比 rfm['用户类型'] = rfm.apply(lambda r: type_map[(r['R_flag'], r['F_flag'], r['M_flag'])], axis=1) type_count = rfm['用户类型'].value_counts() plt.figure(figsize=(10, 6)) sns.barplot(x=type_count.index, y=type_count.values) plt.title('用户类型分布') plt.xticks(rotation=45) plt.show() # 各分层消费金额占比 type_money = rfm.groupby('用户类型')['monetary'].sum() / rfm['monetary'].sum() * 100画出来的结果很有代表性:占用户数不到15%的高价值活跃用户,贡献了将近45%的消费金额;而占用户数超过35%的低价值流失用户,只贡献了不到8%的金额。这类图给业务方看的时候冲击力很强,比念数字管用得多。4.3 将结论落地成运营策略分析的最终输出不是图表而是策略。我把每个用户分层的特征、典型画像和运营建议整理成了一张策略表,并标注了建议的触达频次和渠道偏好。用户类型典型画像建议策略触达方式预计价值高价值活跃近30天有购买,年消费10次以上,客单价高持续维护,优先推送高毛利新品短信+专属客服巩固核心收入高价值沉睡60天以上未购买,历史消费高大额回归礼包、会员积分提醒人工外呼+优惠券高概率召回高价值流失90天以上未购买,历史消费高最后触达一次,超预算则放弃短信+微信止损新用户首次购买30天内7天内复购券,关联推荐高频类目App push拉高首月复购率低价值沉睡低频低额不投入或仅大促触达大促邮件低成本唤醒实操心得:RFM分层不是一次性工作。用户的状态一直在变,分析频率至少要按月滚动。我在项目结束后将这套计算逻辑封装成月度定时任务,月底自动跑一遍,输出新的分层结果给运营侧使用。如果只做一次性分析,价值的衰减会非常快。5. 常见问题与排查技巧实录5.1 数据清洗阶段三个高频坑第一个坑:删除包含缺失值的整行记录时,把有价值的用户信息也删掉了。比如某条订单记录缺失了支付方式字段,但金额和用户ID都正常,如果直接删掉,这个用户的总金额就会少一单。我的处理方式是区分处理:核心字段(金额、时间、用户ID)缺失不可原谅,要删除;非核心字段(支付方式、商品描述)缺失,用“未知”填充或单独归类。第二个坑:订单金额为负数的记录,不全是脏数据。负金额可能是退款订单,也可能是自动核销的优惠补偿。如果统一过滤掉,会低估退款率,影响后续对高价值流失用户的判断。我建议先把负金额订单单独提取出来看业务含义,再做决定。第三个坑:groupby聚合后索引混乱导致join出错。这是新手最容易踩的pandas问题。在构建用户特征表时,如果做完groupby直接和其他表做合并,没有reset_index,会把user_id变成索引而不是列,后面一旦做merge就全部错位。我的习惯是聚合之后立刻reset_index(drop=False),先把索引还原成普通列。5.2 指标计算口径不一致问题分析过程中最大的口径雷区是“用户数”的定义。是统计注册用户数、首购用户数、还是有购买行为的活跃用户数?不同口径算出来的转化率可以差好几倍。我在项目中明确了所有关键指标的口径定义:新用户 = 在某时间段内完成首次下单的用户活跃用户 = 在观察周期内至少有1笔有效订单的用户留存用户 = 在某期首次消费后的第N个周期内再次消费的用户复购用户 = 在观察周期内下单次数大于1的用户每个口径定义都写进了分析文档,并在交付时单独做了一页“指标口径说明”,避免业务方对数字产生歧义。5.3 可视化呈现的避坑要点分析做得再好,图出得乱七八糟也是白费。我在出图阶段总结了几个原则。排序不要默认字母序。比如分层的用户类型如果按字符串排序,“中价值”会出现在“高价值”前面,看起来很不直观。手动指定分类顺序再画图,信息传达效率会高很多。占比图一定要显示具体数字。饼图或堆叠柱状图如果没有数值标签,业务方只能大概看出谁多谁少,看不出“高价值用户只占12%但贡献了40%金额”这种关键结论,分析的说服力就打了折扣。同期群热力图用颜色梯度而不是单一色。我在展示留存率变化时用seaborn的热力图,纵轴是首购月份、横轴是消费周期,色块越深代表留存率越高,一眼就能看出哪个月获取的用户质量更差。避坑建议:不要把结论只写在图里。图表旁边用一句加粗文字写出核心洞察,比如“3月新增用户次月留存率较均值低8个百分点”。很多看报告的人只会扫结论,不会自己从图里提炼信息。6. 这个分析后续还能扩展什么这次项目做到用户分层和策略映射,已经能覆盖大部分日常运营需求,但消费行为分析的方向远不止于此。我在做完首版之后,已经在规划三个扩展方向。第一是用户生命周期价值预测。当前分析是从历史数据看用户已实现的价值,如果能结合用户消费频次、客单价和留存概率做CLV预测,就可以判断一个用户的长期价值是否值得更高的获客成本。第二是流失预警模型。RFM分层能告诉我们哪些用户已经流失或沉睡,但属于事后识别。更有效的做法是用用户近期的行为序列特征训练一个分类模型,在用户流失概率开始升高时就发出预警信号,让运营尽早干预。第三是商品关联推荐。我在这次分析里只做了简单的交叉购买占比统计,下一步可以引入关联规则算法,挖掘品类和商品间的深层关联,直接指导推荐策略。如果团队积累的数据足够多、埋点足够完整,还可以把用户浏览、点击、加购等行为数据也纳入分析,从“订单消费行为”扩展到“完整消费意图链路”,那能看到的东西就更多了。做这种分析项目,我最深的体会是:技术本身并不复杂,pandas不会比Excel难多少,RFM也不是什么高深模型,真正的分水岭在于你有没有把业务问题翻译成数据问题、再把数据结论翻译回业务语言。第一次做的时候我花了很多时间在调颜色、调图表样式上,后来发现业务方根本不在乎这些,他们在乎的是“哪些用户要重点跟、哪些用户可以不跟了、为什么”。把这个想明白,项目就成功了一大半。最后再分享一个小技巧:做完整套分析后,找一个对业务很熟但完全不懂数据的同事,把结论讲给他听,如果他能听懂并且能提问题,那这份分析才算真正接地气了。