import pandas as pd
product=pd.read_excel('日化.xlsx',sheet_name='商品信息表')
order=pd.read_excel('日化.xlsx',sheet_name='销售订单表')
result=pd.merge(order,product,on='商品编号',how='inner')
result
product.info()
order.info()
## (1)缺失值处理
product.isnull().sum()
order.isnull().sum()
order[order['所在区域'].isnull()]
order.loc[order['所在区域'].isnull(),'所在区域']=['东区','南区']
order[order['所在省份']=='广东省']
order.loc[order['所在省份'].isnull(),'所在省份']=['广东省','北京市']
order[order['所在地市']=='北京市']
order.isnull().sum()
order[order['商品编号'].isnull()]#没有订购,不做处理
order[order['订购数量'].isnull()]#订购数量未知,单价无意义,金额无法计算
order[order['订购单价'].isnull()]#商品编号已知可以查询订购单价,订购数量已知,查询单价才有意义
order[(order['订购单价'].isnull()&order['商品编号'].notnull()&order['订购数量'].notnull())]
product[product['商品编号']=='X011']['销售单价'].to_dict()
#product[product['商品编号']=='X011']['销售单价'].to_dict()[10]
list(product[product['商品编号']=='X011']['销售单价'].to_dict().values())[0]
order.loc[order['订单编码']=='D22086','订购单价']=list(product[product['商品编号']=='X011']['销售单价'].to_dict().values())[0]
order.loc[order['订单编码']=='D23111','订购单价']=list(product[product['商品编号']=='X096']['销售单价'].to_dict().values())[0]
order.loc[order['订单编码']=='D22086','金额']=order['订购数量']*order['订购单价']
order.loc[order['订单编码']=='D23111','金额']=order['订购数量']*order['订购单价']
order.isnull().sum()
order.dropna(inplace=True)
order.isnull().sum()
## (2)重复值处理
product[product.duplicated()].count()
order[order.duplicated()].count()
order=order.drop_duplicates()
order.reset_index(drop=True,inplace=True)
#order.drop_duplicates(inplace=True)
#order.index=range(order.shape[0])
order
## (3)转换数据类型
#order['订单日期'].unique()
order['订单日期']=order['订单日期'].apply(lambda x:pd.to_datetime(x,format="%Y#%m#%d") if isinstance(x,str) else x)
order['订单日期']
#isinstance() 判断一个对象是否是一个已知的类型,订单日期中有的数据类型是datetime,有的是str
#如果是str类型就转换为datetime,否则直接返回值
order.shape #查看有多少行多少列
## (4)异常值处理
order[order['订单日期']>'2021-12-23']#一条脏数据
order=order[order['订单日期']<='2021-12-23']#过滤脏数据
order['订单日期'].max(),order['订单日期'].min()#数据区间在2019-01-01到2019-09-30之间
## (5)字符串处理,整理需要用来分析的字段内容
order['订购数量']=order['订购数量'].apply(lambda x:x.strip('个') if isinstance(x,str) else x).astype('int')
order['订购单价']=order['订购单价'].apply(lambda x:x.strip('元') if isinstance(x,str) else x).astype('float')
order['金额']=order['金额'].astype('float')
order['所在省份']=order['所在省份'].str.replace('自治区|维吾尔|回族|壮族|省|市','',regex=True)
order['所在省份'].unique()
order['客户编码']=order['客户编码'].str.replace('编号','')
## (6)每月订购数量及金额情况
#分组统计,分组依据:月;分组的数据:数量、金额
order['订单月份']=order['订单日期'].apply(lambda x:x.month)
#order.groupby('订单月份')['订购数量'].sum()
item=order.groupby('订单月份').agg({'订购数量':'sum','金额':'sum'}).to_dict()
list(item['订购数量'].keys())
[*item['订购数量'].values()]
[x for x in item['金额'].values()]
from pyecharts import options as opts
from pyecharts.charts import Bar,Map
order['订单月份']=order['订单日期'].apply(lambda x:x.month)
#order.groupby('订单月份')['订购数量'].sum()
item=order.groupby('订单月份').agg({'订购数量':'sum','金额':'sum'}).to_dict()
#x=list(item['订购数量'].keys())
#y1=[*item['订购数量'].values()]
y1=[round(i/10000,2) for i in item['订购数量'].values()]
#y2=[x for x in item['金额'].values()]
y2=[round(j/10000/10000,2) for j in item['金额'].values()]
bar=(
Bar()
.add_xaxis([f'{x}月' for x in item['订购数量'].keys()])
.add_yaxis('订购数量(单位:万件)',y1,label_opts=opts.LabelOpts(formatter='{@y1}万件'),is_selected=False)
.add_yaxis('金额(单位:亿元)',y2,label_opts=opts.LabelOpts(formatter='{@y2}亿元'))
.set_global_opts(title_opts=opts.TitleOpts(title="每月订购数量及金额情况"))
)
bar.render('bar.html')
## (7)统计订购数量排行 TOP20的城市
item1 = order.groupby('所在地市').agg({'订购数量':'sum'}).sort_values(by='订购数量',ascending=False)[:20]
item = item1.sort_values(by='订购数量').to_dict()['订购数量']
x=[*item.keys()]
y=[round(v/10000,2) for v in item.values()]
c2=(
Bar()
.add_xaxis(x)
.add_yaxis("订购量",y,
label_opts=opts.LabelOpts(position="right",formatter='{@y} 万'))
.reversal_axis() #x,y轴换方向
.set_global_opts(
title_opts=opts.TitleOpts("订购数量排行 TOP20")
)
)
c2.render('where.html')
## (8)按照订购数量统计美妆类型需求量排序
#(1)堆叠pd.concat([df1,df2],axis=0) (2)主键合并pd.merge(df1,df2,on='key',how='inner') (3)检查数据的缺失值
ord_pro = pd.merge(order,product,on='商品编号',how='inner') #表关联
ord_pro
ord_pro.groupby(['商品大类','商品小类']).agg({'订购数量':'sum'}).sort_values(by=['商品大类','订购数量'],ascending=[True,False])
#by=['商品大类','订购数量'] 按大类降序排序
## (9)统计各省份的美妆需求量分布
item = order.groupby('所在省份').agg({'订购数量':'sum'}).to_dict()['订购数量']
c3 = (
Map()
.add("订购数",[*item.items()],"china",is_map_symbol_show=False)
.set_global_opts(
title_opts=opts.TitleOpts(title='省份分布'),
visualmap_opts=opts.VisualMapOpts(max_=1000000),
)
)
c3.render('sheng.html')
from pyecharts import options as opts
from pyecharts.charts import BMap
from pyecharts.faker import Faker
c = (
BMap()
.add_schema(baidu_ak="FAKE_AK",center=[120.13066322374,30.240018034923])
.add(
"bamp",
[list(z) for z in zip(Faker.provinces,Faker.values())],
label_opts=opts.LabelOpts(formatter="{b}"),
)
.set_global_opts(title_opts=opts.TitleOpts(title="BMap-基本示例"))
)
c.render("bmap_base.html")
## (10)通过 RFM 模型挖掘客户价值
data_rfm=order.groupby('客户编码').agg({'订单日期':'max','订单编码':'count','金额':'sum'})
data_rfm.columns=['最近一次购买时间','消费频率','消费金额']
data_rfm
#rank给出排序的顺序 不影响原数据
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)
美妆类商品数据分析与挖掘
最新推荐文章于 2025-05-14 15:07:12 发布