ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

电商销售数据分析实战:从数据清洗到可视化全流程

电商销售数据分析实战:从数据清洗到可视化全流程 做电商数据分析这个事说起来挺有意思。很多人一开始拿到一份几万行的销售订单表第一反应是“我该用什么模型、要不要上机器学习”结果折腾半天连数据长什么样都没看清楚。我见过太多项目卡在第一步不是工具不够高级而是连“这个月卖了多少、哪个商品拖后腿”这种基础问题都回答不清楚。所以我这篇实战笔记想带你把一份典型的电商销售数据从导入、清洗、指标计算到可视化完整走一遍用的就是Python核心库就是pandas、matplotlib、seaborn这类日常工具。你要是有一定Python基础但没正经做过业务分析或者刚转行数据分析想找个能落地的练手项目这份实操记录值得你跟着敲一遍。先说清楚这个项目能解决什么问题。电商销售数据本身是“脏”的日期格式不统一、金额字段有负数、商品类目填错、用户ID有重复这些不是教科书里的假设而是真实业务里每天都在发生的。整个分析过程我会带着你从数据清洗开始算清楚销售额、订单量、客单价、复购率这几个核心指标再按商品和用户两个维度拆解最后用图表把结论呈现出来。整个过程跑完你能掌握的是一套可以复制到其他业务表上的分析套路而不是一次性代码。1. 项目概述与业务目标1.1 这个项目为什么值得做很多初学者学Python数据分析容易陷入“光学语法、不会用”的尴尬。看教程时numpy和pandas的每个函数都能看懂一拿到真实数据就不知道从哪下手。电商销售数据分析刚好是练习数据分析思维的最佳场景之一因为业务逻辑大家都有体感卖了多少、赚了多少、谁买的、买得什么东西这些问题不需要额外解释。更重要的一点是电商数据集的“脏”程度非常贴近真实环境。你只要用真实业务里的导出数据做一次清洗就会碰上缺失值、异常值、格式混乱、类型错误这些基础问题而这些问题在官方文档的示例数据里几乎不会出现。我自己带新人时最常说的一句话就是能把一张脏表洗到能直接分析你就已经解决了实际工作中一半的问题。这个项目用到的技术点不算难难点全在“怎么根据业务理解去做取舍”上面这才是数据分析真正值钱的部分。1.2 数据从哪来要解决什么业务问题我用的这份模拟数据遵循电商订单表的常见结构主要包含订单编号、下单时间、支付时间、用户ID、商品名称、商品类目、销售数量、订单金额、支付金额、平台优惠、运费等字段。总量大概在五万行左右时间跨度一年覆盖近万名用户。实际项目里你从ERP后台导出的订单明细表结构基本类似只是字段名会有差异比如有的叫“实付款”有的叫“交易成功金额”分析思路是一样的。整个项目围绕三个业务问题展开第一个全年销售大盘怎么样每个月的节奏是什么第二个哪些商品和类目真正贡献利润哪些是虚耗流量第三个用户整体是“一锤子买卖”还是“回头客”高价值用户能拆出多少。这三个问题对应业务上常说的“看大盘、找结构、看用户”不分行业几乎任何零售业务都能套用。我这次分析的模拟数据里这些问题都能得到非常明确的答案后面每个环节会逐个展开。2. 环境准备与数据清洗实战2.1 Python环境搭建与常用库安装开始之前先把环境搞定。我本机用的是Python 3.10通过Anaconda统一管理环境好处是pandas、matplotlib、seaborn这些库都已经预装好了不用一个个手动装。如果你目前是裸Python环境建议直接用pip补齐本轮分析需要的那几个库pip install pandas numpy matplotlib seaborn这几个库的分工要清楚pandas负责表格型数据的读取、清洗、聚合计算numpy主要提供底层数组运算很多场景下pandas会隐式调用它matplotlib是基础绘图库seaborn则是在它之上做统计图表的封装的画热力图、分布图时比直接用matplotlib省代码。我个人习惯用seaborn出图、用matplotlib做细节调整两者搭配效率最高。提示安装过程如果遇到网络超时可以换成国内镜像源比如pip install pandas -i https://pypi.tuna.tsinghua.edu.cn/simple速度会快很多。导入库时有个小细节为了让图表里的中文显示正常需要手动设置字体这一点我会在后面的可视化环节单独讲。先看导入代码import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns # 中文字体配置Windows和Mac有所区别 plt.rcParams[font.sans-serif] [SimHei, Arial Unicode MS] plt.rcParams[axes.unicode_minus] False2.2 数据加载与初步探查拿到数据的第一个动作不是急着算指标而是先看结构。我会先加载数据然后快速过一遍shape、dtypes、head这几个命令df pd.read_csv(sales_data.csv, encodingutf-8) print(df.shape) print(df.dtypes) print(df.head())这一步的目的很纯粹搞清楚有多少行、多少列、每列是什么类型、数据长什么样。一般真实订单表的原始字段会包含订单状态、收货地址、快递单号等一堆分析用不上的信息先看一轮再决定留哪些列比闷头清洗更高效。我这次拿到的数据里冗余字段占了将近四成修剪完只保留业务需要的核心列。然后就是缺失值检查。这里要提醒一下订单表里“支付时间”这列经常有缺失因为不是所有订单都支付成功。缺失值不能一概删除必须先确认是什么业务含义。我检查下来发现支付时间为空的订单对应的是“未支付/已取消”状态所以在清洗环节要先把这部分订单单独分流而不是直接丢进分析样本里。2.3 核心清洗逻辑重复值、异常值与格式统一重复值处理相对直白。订单ID理论上应该是唯一的我查了下确实存在个别重复处理方式是按照“订单号商品名称”做去重判断保留第一次出现的那条记录。操作层面用drop_duplicates()即可但要注意指定判断的列和保留方式否则可能误删有效数据。接下来是异常值。销售数量和订单金额是这次分析的基石字段这两个字段出现负数或极端大值就一定要查。数量为负的实际上是退货订单在业务上不算销售金额异常偏大的可能是测试单。我采用的策略是过滤掉这些数据同时单独保存一份“异常订单表”备查这样既不影响主分析也能保留排查线索。格式统一的重点是日期和时间。原始csv里的下单时间大概率是字符串类型需要转成datetime并且把“下单日期”和“下单小时”拆出来后面做时间趋势和高峰时段分析都要用。具体操作df[order_date] pd.to_datetime(df[order_date]) df[order_month] df[order_date].dt.to_period(M) df[order_hour] df[order_date].dt.hour这一步看起来很基础但我见过不少人栽在这里日期字符串格式不一致转完报错或者转完多了几个空值。稳妥的做法是转格式之前先value_counts()看下有哪些格式再用pd.to_datetime(..., errorscoerce)一次性处理转化失败的行会自动变成NaT后续再排查。整个清洗下来我保留了约四万五千条有效订单。这条数据从“原始可读但不可直接用”变成“干净可分析”的状态整个过程大概投入了四十分钟。说句实在话后面分析速度多快完全取决于这一步做得细不细。3. 核心销售指标计算与业务解读3.1 大盘指标销售额、订单量、客单价大盘指标不用多但每个都得算明白。电商业务最基础也最受关注的三个数字总销售额(GMV)、总订单量、客单价。GMV的定义在不同公司有差异我这里用“支付金额”来算也就是剔除取消订单后实际成交的金额。代码很简洁total_gmv df[pay_amount].sum() total_orders df[order_id].nunique() avg_price total_gmv / total_orders算下来的结果我不贴具体数了但你可以留个印象客单价在两百元上下属于典型的日用快消品类水平。客单价这个指标单独看意义不大但它对后续用户促销策略的制定有直接影响——客单价越高意味着大促满减门槛要往上调。这里想多说一句销售额口径的选择直接决定了你算出来的数跟财务对得上还是对不上。我遇到过不少新人用订单表里的“订单金额”去算GMV结果发现利润薄的产品线连毛利率都是负的后来一查才知道没剔除运费和优惠分摊。所以你在正式做分析前一定要先确认清楚口径或者至少建立起“订单金额、支付金额、实收金额”这三个概念的区别和联系。3.2 时间维度月度趋势与星期分布大盘指标是静止的时间趋势才好看业务节奏。我先按月份聚合看月销售额和订单量的变化同时算环比、同比。环比很好理解就是跟上一个月份比如果手头有去年数据还可以加上去年同月的数据做同比看增长质量。月度趋势几乎每个电商分析场景都要做因为大促活动的效果、季节性品类的起落、新渠道引流带来的增量都会体现在这条折线上。画图这步留到第五节细说但这里把聚合逻辑先跑出来monthly df.groupby(order_month)[pay_amount].agg([sum, count]) monthly[avg_price] monthly[sum] / monthly[count]从结果里能明显看出“双11所在月份”销售额异常拔高这倒是符合预期的正常现象。比较意外的是“6月份”也出现了一个小波峰去看商品明细发现是夏季日用品的集中采买。这就是典型的时间维度发现业务同事看到这个点会立刻追问“能不能把更多商品绑进这个时间窗口做套餐组合”。星期分布是另一个容易被忽略的维度。电商订单有明显的星期效应工作日和周末的消费偏好不同。我按星期几分组看了订单量和客单价结果周末订单量明显上扬但客单价反而略低说明周末更多是零散小额补货类需求。这对广告投放和客服排班都有参考价值。3.3 用户购买力分层为后续精细化运营铺垫大盘知道了商品结构接下来拆但在拆商品之前我更倾向于先给用户做个初步分层因为用户价值决定运营策略运营策略又决定主推哪些商品、定价多少。用到的核心指标是每个用户的累计消费金额和累计消费次数先归一化再按分位数切开。实际操作里我画了一个简单的分位数表把用户按消费金额从高到低排序看前20%的用户贡献了多少销售额。这个思路就是经典的二八法则检验代码也简单user_stats df.groupby(user_id)[pay_amount].agg([sum, count]) user_stats[cumsum_ratio] user_stats[sum].sort_values(ascendingFalse).cumsum() / user_stats[sum].sum()结果显示消费金额排在前20%的用户贡献了超过60%的销售额。这个数字不算极端说明用户结构还算健康高价值用户没到“绑架业绩”的程度。这个结论直接影响后续RFM分层的维度选择金额和频次可以作为核心分层依据但不必过度细分三层足够指导运营动作。4. 商品维度与用户行为深度拆解4.1 商品分析Top榜、类目结构与价格带分布商品维度是电商数据分析里最受业务关注的内容原因很直接卖什么好卖、什么品要淘汰都要从数据里找依据。第一步我按销售额排序做了商品Top20列表。这个列表看起来简单但信息量很大销售额高到底是因为销量高还是因为单价高两者的运营策略完全不同。如果是单价高带起来的销售额那是高客单价爆品活动策划要多给曝光、做搭配销售如果是单价低靠销量堆出来的那是走量款需要控库存、防断货同时评估毛利够不够覆盖物流成本。代码上用groupby加sort_values就能做但只看Top列表有个盲区那些排在后面的长尾商品有没有存在价值我特意看了Top20之后商品的数量占比和销售额占比将近一半的商品贡献不到百分之五的销售额这就是典型的“长尾拖累”——虽然不能说全砍但推广资源肯定不该平均分配。类目结构更能说明问题。我把商品类目和销售额、订单量、客单价做了交叉透视表发现不同类目之间的客单价差异非常悬殊有的类目客单价能到五百以上有的只有几十块。这种差异决定了活动的设计方式高客单价类目适合做满减低客单价类目更适合做第二件半价这类组合购买。价格带是很多新手会忽略的分析角度。我按商品价格分成几档看每个价格带的销量和销售额贡献。这个分析能直接回答“我们的主要销量集中在中低价位还是高价位”对选品定价帮助很大。我这次的模拟数据显示“50到100元区间”是销售主力带而当时正在主推的新品定价却在200元以上这个信息要是早点看产品定价决策可能完全不同。4.2 用户行为分析复购率、购买频次与首次购买时间商品是“货”的角度现在把镜头转到“人”。复购率是衡量用户忠诚度的最基础指标定义有很多种我用的是“统计周期内购买两次及以上的用户数占活跃用户总数的比例”。注意不同口径算出来差异可能很大所以一旦定了口径就要保持一致否则跨期对比没有意义。复购率用代码实现的方式有多种比较直接的是先按用户聚合出购买次数再统计次数2的用户占比user_order_count df.groupby(user_id)[order_id].nunique() repurchase_rate (user_order_count 2).mean()测出来的复购率大概在百分之二十几这个数对快消类电商来说不算高。我看到这个结果的第一反应不是急着下“用户忠诚度差”的结论而是去查了新客占比和首购时间。如果大量用户都是最近半年才进来的百分之二十几的复购率其实还可以接受因为新客还需要时间去积累第二次购买。购买频次分布更有意思。大量用户只买过一次这是正常的漏斗规律但买了五单以上的用户数量虽然少贡献的销售额比例却不低。这批“高频用户”正是RFM模型里的“高价值聚类”也是后面做用户运营的重点触达对象。如果你在真实业务中也发现高频用户集中在某一个区域或某一类商品那一定要深挖那往往是业务的突破口。4.3 RFM分层实战用三个维度把用户划分出运营重点RFM是零售分析里的常青树模型全称是Recency(最近一次购买时间)、Frequency(购买频次)、Monetary(消费金额)。这三个维度拼起来能描述一个用户“最近有没有来、来得多不多、花了多少钱”对电商而言是最经典的用户价值评估框架。实操的时候我不建议直接套公式因为不同业务的购买周期差异太大。比如家具类电商两三个月买一次很正常快消食品却可能每周都买直接统一阈值会失真。我这次的做法是看数据分布来定阈值R维度取最近一次购买距统计截止日期的中位数天数F维度取购买次数的中位数M维度取消费金额的均值。每个维度二分类组合出八大类用户。截取核心代码思路snapshot_date df[order_date].max() rfm df.groupby(user_id).agg({ order_date: lambda x: (snapshot_date - x.max()).days, order_id: count, pay_amount: sum }) rfm.columns [recency, frequency, monetary]分完层之后我重点关注了“重要价值用户”和“重点保持用户”这两组。重要价值用户的特征是“最近买过、买得多、花得多”对应的运营动作简单粗暴给到足够力度的会员权益和上新提醒目的是防御竞争对手挖走他们。重点保持用户特征是“买得多花得多但最近没来”这类用户最值得用召回券刺激一笔复购。这个思路很朴素但真实轮运营里几乎天天用得上。RFM模型在分析圈子里被很多人说“过时”但我一直觉得不是模型问题是用法问题。纯按公式分层给的运营建议确实泛泛但如果结合上一节的商品偏好交叉分析每类用户到底该推什么品RFM完全能落到非常具体的运营动作那就不空了。5. 可视化图表实战与避坑指南5.1 matplotlib中文乱码与横坐标日期过密的处理电商销售数据的可视化第一道坎往往是中文乱码。直接画图你会发现图表标题、图例全部变成方块字这就是默认字体没有对应中文导致的。解决办法前面环境准备那节已经提过核心就是改plt.rcParams里的字体设置。这个配置要放在绘图前统一执行一次而不是每画一张图就设一次。第二道坎是横坐标时间标签挤压。按月看趋势还好如果是按周甚至按天看数据图表底部的时间标签就会叠成一团黑点完全没法读。我处理这个问题有三个常用方案一是旋转标签简单省事但不能根本解决二是隔几个点显示一个标签用plt.xticks()手工指定三是把图表尺寸拉宽让每个标签有足够空间。实际操作中我习惯先拉长尺寸再隔点显示两招组合基本能解决绝大多数过密情况。fig, ax plt.subplots(figsize(12, 6)) plt.xticks(ticksrange(0, len(monthly), 3), labelsmonthly.index[::3], rotation30)5.2 用组合图快速定位业务问题可视化不是把图表堆出来而是每张图都有自己的分析目标。我做这次分析时最常用的是组合图柱状图加折线图叠加。柱状表示订单量折线表示客单价两者用双Y轴展示目的是快速判断“订单量涨的时候客单价有没有跟着涨”如果订单量上了但客单价掉了说明增长的质量不健康可能是低价促销带来的虚假繁荣。订单状态分布用饼图看最直观但饼图我觉得不是最好的选择因为类别一多就分不清谁大谁小。这几次我改用横向条形图数据标签直接标在末尾一眼就能定位占比结构。分析销售数据时我自己有套选图心法看变化用折线、看排名用条形、看构成用堆叠柱状、看分布用箱线图。不要为了炫技硬上复杂图表业务方看不懂的可视化就是失败的。5.3 三张核心图表带你建立分析直觉每次做这类分析我会固定产出三张核心图表它们基本能覆盖老板和运营最关心的信息。第一张是全年度月度销售额趋势线。这张图贴出来之后全年什么时候冲刺、什么时候淡季一目了然预算和人力安排都能对上。第二张是商品类目销售额对比条形图。这张图要能看出头部类目和长尾类目的差距方便确定资源投放重点。第三张是用户分层占比堆叠图或者分组柱状图重点表现“有多少用户贡献了主要销售额”。这三张图都做出来一次完整的业务汇报素材基本就齐了。再强调一下配色问题。seaborn默认的配色整体观感还行但如果你做商务汇报建议手动调成柔和、低饱和度的色板。花里胡哨的颜色看起来“科技感”很强但在严肃业务分析场景里反而会干扰判断。另外所有图表都要加标题和轴标签数据标签见机加——信息量适中才是最好的不是越多越好。6. 实战中的常见问题与排查技巧6.1 数据量过大导致运行慢的优化手段电商销售数据动辄几十万行在小笔记本上跑pandas的groupby有时会卡得让人崩溃。我第一次跑这份数据时也遇到了同样问题排查之后发现主要瓶颈不是数据量本身而是聚合维度过多、中间过程反复拷贝数据。优化手段排序下来收益最明显的有三个。第一个是在聚合之前先只保留分析需要的字段把几十列砍到十来列。第二个是尽量避免apply里写循环逻辑能用内置聚合函数就一律用内置函数。第三个是如果内存还是吃紧可以用category类型压缩类目字段对字符串列做astype(category)有时能砍掉一大半内存。df[category] df[category].astype(category)真实项目里如果数据量超过几百万行我通常会建议换用polars或者上SQL但那是另一个话题了。对大多数中小型电商的订单明细来说pandas优化后完全够用。6.2 时间字段转换失败与金额口径不一致时间字段转换是本项目里最容易踩坑的一环。原始数据里的订单时间格式五花八门有的是“2024-01-05 12:23:44”有的是“2024/1/5 12:23”还有个别是纯文本。统一转换建议直接用pd.to_datetime(column, formatmixed)它会自动识别不同格式。如果还是报错就用errorscoerce把无法解析的行置成NaT再单独排查。金额口径不一致的问题更隐蔽。我拿到这张表时发现“订单金额”和“支付金额”之间存在差异有些订单的支付金额等于订单金额加运费有些却是减掉优惠后的结果。后来我仔细核对了字段说明文档才确认平台优惠和运费在两条路径上的处理方式不同。这个坑没有捷径只能靠业务理解去对冲至少你要知道每个字段的定义再动手算。6.3 极简排查清单与避坑心得结合我反复做这类项目的经验给你整理一份上手就能用的踩坑清单groupby之后如果结果跟你预期不一致优先检查是不是前面清洗时丢失了部分行尤其是过滤条件是否误伤正常数据。计算复购率时订单号用nunique去重别用count否则一单多商品会虚增购买次数。先按金额排序再算累计占比别直接对原始数据做cumsum。做RFM分层前先把缺失用户过滤干净否则分层结果会带偏。保存最终图表时用dpi150或更高防止导出后图片模糊。这几点看起来都是细节但任何一个出错呈现出来的分析结论都可能差出十万八千里。我早期做项目时就因为复购率误把订单数当人数直接给业务方报了个偏高一倍的数后来核对才发现整个过程非常尴尬。从那之后每次算指标之前我都会在草稿纸上先写一遍业务公式再对照代码里到底算的是哪个字段。6.4 汇总一张速查表供日常参考问题场景常见原因排查/解决手段中文标签全变方块默认字体不支持中文设置plt.rcParams[font.sans-serif]指定中文字体日期转换报错源数据格式混杂或含非法值用errorscoerce转NaT后单独排查销售金额出现负数存在退款订单先确认业务含义必要时单列退款分析聚合速度过慢列数过多且反复拷贝只保留分析字段并尝试压缩类型横坐标标签重叠时间粒度太细隔点显示标签、旋转角度、放大画布客单价异常波动未剔除未支付订单清洗阶段把支付状态筛出来再算复购率虚高使用订单数而非用户数统一用nunique对用户ID去重按月趋势缺数据存在大段时间空档检查源数据时间范围必要时补NULL月份这张表是我日常做电商分析时翻看频率最高的内容虽然场景不算多但覆盖面基本能应对常见交付。写在最后这套分析能力可以怎么延伸这次从零到一跑完电商销售数据分析你会发现核心能力其实并不复杂能理解数据里的业务含义、能把脏数据洗到能用的状态、能选择合适的指标回答具体问题、能把结论画成让人秒懂的图表。这四件事做扎实了不管换到哪个行业的数据分析项目你都能快速迁移。我个人在实际操作中最大的体会是所有模型和算法都排在“先把业务问题问清楚”之后。拿到数据先定义一个最想解决的具体问题比闷头把能算的指标全算一遍要有用得多。如果你后续想把这个项目继续扩展有两个方向建议先试试一是引入订单退换货数据做退款率归因分析你会发现很多商品质量问题其实是可以用数据说话的二是把用户分层和商品偏好做交叉生成“高价值用户最爱买什么”的清单这份清单在运营眼里比任何统计模型都直接。最后再分享一个小技巧分析做完之后养成把清洗逻辑和数据口径写成文字备注的习惯。隔一个月再回看项目时这些备注能帮你节省大量回忆时间。数据是会过期的但方法和经验不会。希望这篇实战笔记对你的下一个分析项目有帮助。
返回列表