算法学习
、4对1辅导
、论文辅导
、核心期刊
项目的代码和数据下载
可以通过公众号
滴滴我
文章目录
项目说明
【7万条天猫订单数据分析】案例是一个包含代码和数据集的数据分析项目,主要涉及数据清洗、数据分析和可视化的过程。该案例采用离线处理方式,使用的技术栈包括pandas库进行数据清洗和分析,以及pyecharts库进行数据可视化,整个项目在jupyter notebook环境下完成。
-
内容概要: 通过对7万条天猫订单数据进行分析,探索订单数据的特征、趋势和规律,从而为商家提供决策支持和业务优化建议。
-
适用人群: 适合对数据分析感兴趣的数据分析师、数据科学家、商业分析师等人群,也适合希望了解如何利用Python进行数据清洗、分析和可视化的初学者。
-
使用场景及目标: 该案例适用于电商领域的数据分析,可用于分析用户购买行为、产品销售情况、营销策略效果等方面。通过分析订单数据,可以发现用户购买偏好、热门商品、销售季节性等信息,帮助商家优化产品推广、库存管理和营销策略,提高销售效益。
-
其他说明: 该案例中的数据集规模较大,需要一定的数据处理和分析能力。通过学习该案例,可以掌握使用Python进行数据清洗、分析和可视化的基本方法,提升数据分析能力和实践经验。
Part 1
1、数据说明及分析目录
tmall_order_report.csv
这个数据集是订单数据,可供挖掘的维度有订单时间、省份(收货地址)。另外本数据集共收集了一个月内的28010条数据。
主要字段包括:订单编号
、买家实际交付金额
、收货地址
、订单创建时间
、订单付款时间
、退款金额
- 订单实际支付金额 = 订单总金额 - 退款金额
- 若付款时间为NAN,则这订单未支付。且退款金额为0
另外此项目的业务逻辑是
分析目的:
- 订单每个环节的转化情况
- 订单成交的时间特点
- 各区域订单情况
2、数据理解与处理
import pandas as pd
data = pd.read_csv('tmall_order_report.csv')
data.head() # 退款金额应该就是客户退货后,返还给客户的退款金额
data.info() # 数据集情况 28010 条,6个字段
data.columns = data.columns.str.strip() # 列名有空格,需要处理下
data.columns
data[data.duplicated()].count() # 没有完全重复的数据
data.isnull().sum() # 付款时间存在空值,表示订单未付款
data['收货地址'] = data['收货地址'].str.replace('自治区|维吾尔|回族|壮族|省', '') # 对省份做个清洗,便于可视化
data['收货地址'].unique()
3、数据分析可视化
3.1 整体情况
result = {}
result['总订单数'] = data['订单编号'].count()
result['已完成订单数'] = data['订单编号'][data['订单付款时间'].notnull()].count()
result['未付款订单数'] = data['订单编号'][data['订单付款时间'].isnull()].count()
result['退款订单数'] = data['订单编号'][data['退款金额'] > 0].count()
result['总订单金额'] = data['总金额'][data['订单付款时间'].notnull()].sum()
result['总退款金额'] = data['退款金额'][data['订单付款时间'].notnull()].sum()
result['总实际收入金额'] = data['买家实际支付金额'][data['订单付款时间'].notnull()].sum()
result
from pyecharts import options as opts
from pyecharts.charts import Map, Bar, Line
from pyecharts.components import Table
from pyecharts.options import ComponentTitleOpts
from pyecharts.faker import Faker
table = Table()
headers = ['总订单数', '总订单金额', '已完成订单数', '总实际收入金额', '退款订单数', '总退款金额', '成交率', '退货率']
rows = [
[
result['总订单数'], f"{result['总订单金额']/10000:.2f} 万", result['已完成订单数'], f"{result['总实际收入金额']/10000:.2f} 万",
result['退款订单数'], f"{result['总退款金额']/10000:.2f} 万",
f"{result['已完成订单数']/result['总订单数']:.2%}",
f"{result['退款订单数']/result['已完成订单数']:.2%}",
]
]
table.add(headers, rows)
table.set_global_opts(
title_opts=ComponentTitleOpts(title='整体情况')
)
table.render_notebook()
3.2 地区分析
result2 = data[data['订单付款时间'].notnull()].groupby('收货地址').agg({'订单编号':'count'})
result21 = result2.to_dict()['订单编号']
c = (
Map()
.add("订单量", [*result21.items()], "china", is_map_symbol_show=False)
.set_series_opts(label_opts=opts.LabelOpts(is_show=True))
.set_global_opts(
title_opts=opts.TitleOpts(title='地区分布'),
visualmap_opts=opts.VisualMapOpts(max_=1000),
)
)
c.render_notebook()
3.3 时间分析
data['订单创建时间'] = pd.to_datetime(data['订单创建时间'])
data['订单付款时间'] = pd.to_datetime(data['订单付款时间'])
result31 = data.groupby(data['订单创建时间'].apply(lambda x: x.strftime("%Y-%m-%d"))).agg({'订单编号':'count'}).to_dict()['订单编号']
c = (
Line()
.add_xaxis(list(result31.keys()))
.add_yaxis("订单量", list(result31.values()))
.set_series_opts(
label_opts=opts.LabelOpts(is_show=False),
markpoint_opts=opts.MarkPointOpts(
data=[
opts.MarkPointItem(type_="max", name="最大值"),
]
),
)
.set_global_opts(title_opts=opts.TitleOpts(title="每日订单量走势"))
)
c.render_notebook()
从上图来看,2月份上半月由于受新冠疫情影响,订单量比较少,随着复工开展,下半月的订单量增长明显。
result32 = data.groupby(data['订单创建时间'].apply(lambda x: x.strftime("%H"))).agg({'订单编号':'count'}).to_dict()['订单编号']
x = [*result32.keys()]
y = [*result32.values()]
c = (
Bar()
.add_xaxis(x)
.add_yaxis("订单量", y)
.set_global_opts(title_opts=opts.TitleOpts(title="每小时订单量走势"))
.set_series_opts(
label_opts=opts.LabelOpts(is_show=False),
markpoint_opts=opts.MarkPointOpts(
data=[
opts.MarkPointItem(type_="max", name="峰值"),
opts.MarkPointItem(name="第二峰值", coord=[x[15], y[15]], value=y[15]),
opts.MarkPointItem(name="第三峰值", coord=[x[10], y[10]], value=y[10]),
]
),
)
)
c.render_notebook()
从每小时订单量走势来看,一天中有3个高峰期(10点、15点、21点),其中21点-22点之间是一天中订单量最多的时候,这个结果和之前 1 亿条淘宝用户行为数据分析 的结果是一致的。对于卖家的指导意义就是,为了提高订单量,高峰期时应该尽量保证客服的回复速度,尤其是晚上21点-22点之间,所以很多做电商的基本都有夜班。
s = data['订单付款时间'] - data['订单创建时间']
s[s.notnull()].apply(lambda x: x.seconds / 60 ).mean() # 从下单到付款的平均耗时为 7.7 分钟
Part 2
1、数据说明及分析目录
双十一淘宝美妆数据.csv
这个数据集是双十一销售数据,可供挖掘的维度有日期
、店铺
,指标则有销售量
、销售额
、评论数
等。本数据集共28010条数据。
主要字段包括:update_time
、id
、title
、price
、sale_count
、comment_count
、店名
2、数据理解及处理
import pandas as pd
data2 = pd.read_csv('双十一淘宝美妆数据.csv')
data2.head()
data2.info() # 数据集情况 28010 条,6个字段
data2[data2.duplicated()].count() # 有86条完全重复数据
data2.drop_duplicates(inplace=True) # 删除重复数据
data2.reset_index(drop=True, inplace=True) # 重建索引
data2.isnull().sum() # 查看空值 ,销售数量和评论数有空值
data2.fillna(0, inplace=True) # 空值填充
data2['update_time'] = pd.to_datetime(data2['update_time']).apply(lambda x: x.strftime("%Y-%m-%d")) # 日期格式化,便于统计
data2[data2['sale_count']>0].sort_values(by=['sale_count']).head() # 从数据来看,sale_count 是销售量
data2['sale_amount'] = data2['price'] * data2['sale_count'] # 增加一列销售额
data2[data2['sale_count']>0].sort_values(by=['sale_count'])
3、数据分析与可视化
3.1 每日整体销售量走势
result = data2.groupby('update_time').agg({'sale_count':'sum'}).to_dict()['sale_count']
c = (
Line()
.add_xaxis(list(result.keys()))
.add_yaxis("销售量", list(result.values()))
.set_series_opts(
areastyle_opts=opts.AreaStyleOpts(opacity=0.5),
label_opts=opts.LabelOpts(is_show=False),
markpoint_opts=opts.MarkPointOpts(
data=[
opts.MarkPointItem(type_="max", name="最大值"),
opts.MarkPointItem(type_="min", name="最小值"),
opts.MarkPointItem(type_="average", name="平均值"),
]
),
)
.set_global_opts(title_opts=opts.TitleOpts(title="每日整体销售量走势"))
)
c.render_notebook()
3.2 谁家的化妆品卖的最好
dts = list(data2['update_time'].unique())
dts.reverse()
dts
from pyecharts import options as opts
from pyecharts.charts import Map, Timeline, Bar, Line, Pie
from pyecharts.components import Table
from pyecharts.options import ComponentTitleOpts
tl = Timeline()
tl.add_schema(
# is_auto_play=True,
is_loop_play=False,
play_interval=500,
)
for dt in dts:
item = data2[data2['update_time'] <= dt].groupby('店名').agg({'sale_count': 'sum', 'sale_amount': 'sum'}).sort_values(by='sale_count', ascending=False)[:10].sort_values(by='sale_count').to_dict()
bar = (
Bar()
.add_xaxis([*item['sale_count'].keys()])
.add_yaxis("销售量", [round(val/10000,2) for val in item['sale_count'].values()], label_opts=opts.LabelOpts(position="right", formatter='{@[1]/} 万'))
.add_yaxis("销售额", [round(val/10000/10000,2) for val in item['sale_amount'].values()], label_opts=opts.LabelOpts(position="right", formatter='{@[1]/} 亿元'))
.reversal_axis()
.set_global_opts(
title_opts=opts.TitleOpts("累计销售量排行 TOP10")
)
)
tl.add(bar, dt)
tl.render_notebook()
item = data2.groupby('店名').agg({'sale_count': 'sum'}).sort_values(by='sale_count', ascending=False)[:10].to_dict()['sale_count']
item = {k: round(v/10000, 2) for k, v in item.items()}
c = (
Pie()
.add("销量", [*item.items()])
.set_series_opts(label_opts=opts.LabelOpts(formatter="{b}: {c} 万({d}%)"))
)
c.render_notebook()
3.3 谁家的化妆品最贵
item = data2.groupby('店名').agg({'price': 'mean'}).sort_values(by='price', ascending=False)[:20].sort_values(by='price').to_dict()
c = (
Bar()
.add_xaxis([*item['price'].keys()])
.add_yaxis("销售量", [round(v, 2) for v in item['price'].values()], label_opts=opts.LabelOpts(position="right"))
.reversal_axis()
.set_global_opts(
title_opts=opts.TitleOpts("平均价格排行 TOP20")
)
)
c.render_notebook()
Part3
1、数据说明及分析目录
日化.xlsx 这个数据集是美妆类商品的订单数据,从数量来看,应该是批发类的订单。包含两个 sheet 页(订单表和商品表),可以挖掘的纬度有日期、地区、商品,指标则有销售量、销售额、增长率等。
日化.xlsx
这个数据集是美妆类商品的订单数据,可供挖掘的维度有日期
、地区
、商品
,指标则有销售量
、销售额
、增长率
等。
2、数据理解与处理
import pandas as pd
fact_order = pd.read_excel('日化.xlsx', sheet_name='销售订单表')
dim_product = pd.read_excel('日化.xlsx', sheet_name='商品信息表')
2.1 商品表数据清洗
dim_product.head()
dim_product.describe()
dim_product[dim_product.duplicated()].count() # 没有完全重复的数据
dim_product[dim_product['商品编号'].duplicated()].count() # ID 唯一没有重复
dim_product.isnull().sum() # 没有空值
2.2 订单表数据清洗
fact_order.head()
fact_order.info()
fact_order[fact_order.duplicated()].count() # 没有完全重复的数据
fact_order.drop_duplicates(inplace=True) # 删除重复数据
fact_order.reset_index(drop=True, inplace=True) # 重建索引
fact_order.isnull().sum() # 查看空值,有几条数据缺失
fact_order.fillna(method='bfill', inplace=True) # 空值填充
fact_order.fillna(method='ffill', inplace=True) # 空值填充
fact_order.isnull().sum() # 查看空值,有几条数据缺失
fact_order['订单日期'] = fact_order['订单日期'].apply(lambda x: pd.to_datetime(x, format='%Y#%m#%d') if isinstance(x, str) else x)
fact_order[fact_order['订单日期'] > '2021-01-01'] # 有一条脏数据
fact_order = fact_order[fact_order['订单日期'] < '2021-01-01'] # 过滤掉脏数据
fact_order['订单日期'].max(), fact_order['订单日期'].min() # 数据区间在 2019-01-01 到 2019-09-30 之间
fact_order['订购数量'] = fact_order['订购数量'].apply(lambda x: x.strip('个') if isinstance(x, str) else x).astype('int')
fact_order['订购单价'] = fact_order['订购单价'].apply(lambda x: x.strip('元') if isinstance(x, str) else x).astype('float')
fact_order['金额'] = fact_order['金额'].astype('float')
fact_order.info()
fact_order['所在省份'] = fact_order['所在省份'].str.replace('自治区|维吾尔|回族|壮族|省|市', '') # 对省份做个清洗,便于可视化
fact_order['所在省份'].unique()
fact_order['客户编码'] = fact_order['客户编码'].str.replace('编号', '')
3、数据分析与可视化
3.1 每月订购情况
from pyecharts import options as opts
from pyecharts.charts import Map, Bar, Line
from pyecharts.components import Table
from pyecharts.options import ComponentTitleOpts
from pyecharts.faker import Faker
fact_order['订单月份'] = fact_order['订单日期'].apply(lambda x: x.month)
item = fact_order.groupby('订单月份').agg({'订购数量': 'sum', '金额': 'sum'}).to_dict()
x = [f'{key} 月' for key in item['订购数量'].keys()]
y1 = [round(val/10000, 2) for val in item['订购数量'].values()]
y2 = [round(val/10000/10000, 2) for val in item['金额'].values()]
c = (
Bar()
.add_xaxis(x)
.add_yaxis("订购数量(万件)", y1, is_selected=False)
.add_yaxis("金额(亿元)", y2)
.set_global_opts(title_opts=opts.TitleOpts(title="每月订购情况"))
.set_series_opts(
label_opts=opts.LabelOpts(is_show=True),
)
)
c.render_notebook()
3.2 哪里的人最爱美
item = fact_order.groupby('所在地市').agg({'订购数量': 'sum'}).sort_values(by='订购数量', ascending=False)[:20].sort_values(by='订购数量').to_dict()['订购数量']
c = (
Bar()
.add_xaxis([*item.keys()])
.add_yaxis("订购量", [round(v/10000, 2) for v in item.values()], label_opts=opts.LabelOpts(position="right", formatter='{@[1]/} 万'))
.reversal_axis()
.set_global_opts(
title_opts=opts.TitleOpts("订购数量排行 TOP20")
)
)
c.render_notebook()
3.3 什么类型的美妆需求量最大
order = pd.merge(fact_order, dim_product, on='商品编号',how='inner') # 表关联
order
order.groupby(['商品大类','商品小类']).agg({'订购数量': 'sum'}).sort_values(by=['商品大类', '订购数量'], ascending=[True, False])
3.4 哪些省份的美妆需求量最大
item = fact_order.groupby('所在省份').agg({'订购数量': 'sum'}).to_dict()['订购数量']
c = (
Map()
.add("订购数量", [*item.items()], "china", is_map_symbol_show=False)
.set_series_opts(label_opts=opts.LabelOpts(is_show=True))
.set_global_opts(
title_opts=opts.TitleOpts(title='省份分布'),
visualmap_opts=opts.VisualMapOpts(max_=1000000),
)
)
c.render_notebook()
3.5 通过 RFM 模型挖掘客户价值
RFM 模型是衡量客户价值和客户创利能力的重要工具和手段,其中由3个要素构成了数据分析最好的指标,分别是:
- R-Recency(最近一次购买时间)
- F-Frequency(消费频率)
- M-Money(消费金额)
设定一个计算权重,比如 R-Recency 20% F-Frequency 30% M-Money 50% ,最后通过这个权重进行打分,量化客户价值,后续还可以基于分数进一步打标签,用来指导二次营销的策略。
data_rfm = fact_order.groupby('客户编码').agg({'订单日期': 'max', '订单编码': 'count', '金额': 'sum'})
data_rfm.columns = ['最近一次购买时间', '消费频率', '消费金额']
data_rfm['R'] = data_rfm['最近一次购买时间'].rank(pct=True) # 转化为排名 百分比,便于后续切片
data_rfm['F'] = data_rfm['消费频率'].rank(pct=True)
data_rfm['M'] = data_rfm['消费金额'].rank(pct=True)
data_rfm.sort_values(by='R', ascending=False)
data_rfm['score'] = data_rfm['R'] * 20 + data_rfm['F'] * 30 + data_rfm['M'] * 50
data_rfm['score'] = data_rfm['score'].round(1)
data_rfm.sort_values(by='score', ascending=False)
根据这个分数结果,我们可以对客户打上一些标签,比如大于 80 分的,标志为优质客户,在资源有限的情况下,可以优先服务好优质客户。