一、选题背景
原因:对电子商务进行分析,利用任何可能影响销售的信息,了解当前趋势和消费者行为的变化,进行数据驱动决策,以增加在线销售额。电子商务分析利用与整个用户路径相关的指标,从发现、获取、转换、保留和推荐。
目标:分析年龄分布、性别比例、以及RFM模型的建立,用户行为分析。
二、设计方案
- 数据内容:主要包含了购物时间,购物id,商品id,种类id,商铺名词,价格,以及用户id,性别年龄,以及地址。如下是初始信息的概览。
特征分析:某些列的数据类型是object类型,需要进行处理方便后续分析,根据event_time,price,product_id(category_id),可以进行RFM模型的分析。
三、数据分析步骤
- 数据源:淘宝购买,为电商用户数据
- 数据清洗:
首先从数据的格式入手,将event_data进行处理,转换成日期格式,并提取出年份、月份、日期等信息
接着对其他列进行简单的格式转化,化成统一的格式。
最后对空值,缺失值和重复值进行处理
3.分析过程
(1) 统计每个订单的价格,并进行表格合并,新增总价列,并筛选出日期大于20201.1的信息,将信息保存进新的文件。
(2) 进行用户年龄和性别分布的统计
(3) 年龄分布:
(4) 标记高潜用户(最早交互时间和最后购买时间的差值)
计算每类商品每个用户最后的购买时间,最早与该商品发生交互的日期,最后购买时间,并计算时间差,规定若是时间差大于3,就标记为高潜用户。
(5)RFM模型的建立
RFM模型是衡量客户价值和客户创造利益能力的重要工具和手段。在众多的客户关系管理(CRM)的分析模式中,RFM模型是被广泛提到的。该机械模型通过一个客户的近期购买行为、购买的总体频率以及花了多少钱3项指标来描述该客户的价值状况。本次分析以以下标准划分RFM模型。
最终得到如下所示的分类:
由图可知,消费水平处在中间的人数相对较多。
4.数据可视化:
如图为性别分布可视化:
如图为年龄分布可视化:
如图为RFM模型分类以后的图示:
分析价格分布,可以看出0-30和300+的商品占比较多
销售额与省份之间的关系,经济发达的省份,购买力比较强
价格对购买数量的影响
一天中,pv,pu的变化趋势。
一周中,pv,pu的变化趋势。
5.源码:
import numpy as np import pandas as pd import warnings from datetime import datetime #忽略警告 warnings.filterwarnings("ignore") #读取数据 data = pd.read_csv(r"D:\数据分析用到的源文件\电子产品销售分析.csv",index_col = 0) #概览信息 data.info() data.shape #对event_time进行处理 f = lambda x:x.split(" ")[0] #提取日期 data["date"] = data["event_time"].map(f) # 转换为日期格式 data['date'] = pd.to_datetime(data['date']) data.head() #提取月份 data['month'] = data['date'].dt.month #提取小时 data["hour"] = data["event_time"].apply(lambda x:x.split(" ")[1].split(":")[0]) #提取星期 data["week"] = data['date'].apply(lambda x:x.strftime('%w')) data.head() data1 = data.drop("event_time",axis = 1) # 类型转换 data1['hour'] = data1['hour'].astype('int64') data1['week'] = data1['week'].astype('int64') data1['category_id'] = data1['category_id'].astype('object') data1['user_id'] = data1['user_id'].astype('object') data1['age'] = data1['age'].astype('int64') data1.info() data1.describe() #缺失值处理 data1["category_code"] = data1["category_code"].fillna("NA") data1 = data1[data1["brand"].notnull()] data1[data1["brand"].isnull()] #重复值 data1.duplicated().sum() #统计每个订单的总价 #同一订单,同一产品的购买数量 df = data1.groupby(["order_id","product_id"]).agg(buy_num = ("user_id","count")) #进行表合并 data2 = pd.merge(data1,df,on = ["order_id","product_id"],how = "inner") data2 = data2.reset_index(drop = True) data2.head() #新增总价列 data2["amount"] = data2["price"] * data2["buy_num"] data2.head() #异常值 data2.describe() #显示所有 data2.describe(include = "all") data3 = data2[data2['date'] > '2020-01-01'] data3 = data3.reset_index(drop=True) data3.head() #保存文件 data3.to_csv(r'D:\数据分析用到的源文件\data_clean.csv') #用户性别分布 gender = data3.groupby(by="sex").agg({'user_id':pd.Series.nunique}).reset_index() gender["sex"] = ["男","女"] data_pair = [(i,j) for i,j in zip(gender["sex"],gender["user_id"])] data_pair from pyecharts.charts import Pie import pyecharts.options as opts from pyecharts.charts import Bar chart = Pie(init_opts=opts.InitOpts(theme = "light",width = "700px",height="700px")) chart.add( "", data_pair, radius=["30%","45%"], label_opts=opts.LabelOpts(formatter="{b}:{d}%") ) chart.set_global_opts(title_opts=opts.TitleOpts(title="顾客性别分析",pos_left="center"), legend_opts=opts.LegendOpts( is_show = True, pos_left = "center", pos_top = "5%" ) ) chart.render_notebook() #年龄分布情况 user_age_count = data3.groupby(by="age").count() user_age_count from pyecharts.charts import Bar x_data = user_age_count.index.tolist() y_data = user_age_count["sex"].values.tolist() #绘图 bar = ( Bar() .add_xaxis(x_data) .add_yaxis("柱形图",y_data) .set_series_opts(label_ops=opts.LabelOpts(is_show=True,position="insideTop")) .set_global_opts(title_opts={"text":"年龄分布"}) ) bar.render_notebook() #计算每类商品每个用户最后的购买时间 ac_lastbuytime = data3.groupby(by=["user_id"])["date"].apply(lambda x : x.max()) ac_lastbuytime #最早与该商品发生交互的日期 ac_all_buy = pd.merge(ac_lastbuytime,data3,left_on="user_id",right_on="user_id") ac_all_buy.head() ac_firsttime = ac_all_buy.groupby(by="user_id")["date_y"].apply(lambda x:x.min()) ac_firsttime #最早交互时间和最后购买时间的差值 df = pd.merge(ac_firsttime.to_frame(),ac_lastbuytime,on = "user_id") df.columns = ["buytime","ac_time"] #计算时间差 df["day"] = (pd.to_datetime(df["ac_time"]) - pd.to_datetime(df["buytime"])).dt.days #获取高潜用户 hight_pot = df[df["day"]>1] hight_pot df = data.pivot_table( index = "user_id", values = ["date","category_id","price"], aggfunc={"date":"max","category_id":"count","price":"sum"} ) df.columns = ['InvoiceNo','InvoiceDate','total'] df["R"] = (df["InvoiceDate"].max() - df["InvoiceDate"]).dt.days #dt.days 计算天数 df.rename(columns={"InvoiceNo":"F","total":"M"},inplace = True) rfmdf = df[["R","F","M"]] def fun(x): label = { "111":"重要价值客户", "101":"重要发展客户", "011":"重要保持客户", "001":"重要挽留客户", "110":"一般价值客户", "100":"一般发展客户", "010":"一般保持客户", "000":"一般挽留客户" } return label[x["R"]+x["F"]+x["M"]] #该值>大于该列平均值,则设置为1,否则设置为0 #用均值对用户进行分层 rfmdf = rfmdf.apply(lambda x:x-x.mean()) rfmdf = rfmdf.applymap(lambda x:"1" if x>0 else "0") rfmdf["label"] = rfmdf.apply(fun,axis=1) #统计各等级客户数量 rfmdf.groupby(by="label").size() #size()与count()有区别 import matplotlib.pyplot as plt plt.rcParams["font.sans-serif"] = ["SimHei"] plt.rcParams["font.size"] = 20 rfmdf["label"].value_counts().plot.bar(figsize = (20,9),color="red",alpha = 0.5) plt.xticks(rotation=0) for i,j in enumerate(rfmdf["label"].value_counts()): plt.text(i-0.1,j+1000,j,va="center") #分析R,M之间的关系 from random import sample time = np.array(sample(list(data["R"]),k= 200)) price =np.array(sample(list(data["M"]),k= 200)) from sklearn.model_selection import train_test_split #这是划分训练集和测试集的 from sklearn.linear_model import LinearRegression import matplotlib.pyplot as plt plt.rcParams["font.sans-serif"] = ['SimHei'] plt.rcParams["axes.unicode_minus"] = False time = time.reshape(-1,1) time = np.array(time,dtype="float") time[:,0] = (time[:,0] - np.mean(time[:,0]))/np.std(time[:,0]) price = price.reshape(-1,1) price = np.array(price,dtype="float") price[:,0] = (price[:,0] - np.mean(price[:,0]))/np.std(price[:,0]) plt.scatter(price,time) plt.show() clean_data = pd.read_csv(r'D:\数据分析用到的源文件\data_clean.csv') clean_data price = clean_data["price"] #分析价格分布 扇形图 n1=0 n2=0 n3=0 n4=0 n5=0 n6=0 n7=0 n8=0 n9=0 n10=0 for i in range(len(price)): num=int(float(price[i])) if 0<=num<30: n1+=1 elif 30<=num<60: n2+=1 elif 60<=num<90: n3+=1 elif 90<=num<120: n4+=1 elif 120<=num<150: n5+=1 elif 150<=num<180: n6+=1 elif 180<=num<210: n7+=1 elif 210<=num<240: n8+=1 elif 240<=num<300: n9+=1 else: n10+=1 # 用Matplotlib画饼图 nums=[n1,n2,n3,n4,n5,n6,n7,n8,n9,n10] labels=["0-30","30-60","60-90","90-120","120-150","150-180","180-210","210-240","240-300","300up"] plt.pie(x = nums, labels=labels) plt.show() data2 = clean_data.groupby(["brand"],as_index=False).sum() name = data2["brand"][0:5] num = data2["price"][0:5] import matplotlib.pyplot as plt plt.xticks(range(len(name)),name) plt.bar(range(len(num)), num) data3 = clean_data.groupby(["local"],as_index=False).sum() data3 provicen = data3["local"] sum_ = data3["amount"] plt.plot(provicen,sum_) num_1 = clean_data[clean_data["price"]<=60] t1 = num_1["buy_num"].mean() num_2 = clean_data[(clean_data['price'] >= 60) & (clean_data['price'] <= 300)] t2 = num_2["buy_num"].mean() num_3 = clean_data[(clean_data['price'] > 300) & (clean_data['price'] <= 1000)] t3 = num_3["buy_num"].mean() num_4 = clean_data[clean_data["price"]>1000] t4 = num_4["buy_num"].mean() num = [t1,t2,t3,t4] name = ["0-60","60-300","300-1000","1000+"] plt.plot(name,num) df_day = clean_data.groupby(["date","order_id"]).mean() df_day pv_hour = clean_data.groupby("hour")['user_id'].count() pv_hour.head() uv_hour = clean_data.groupby("hour")['user_id'].apply(lambda x: x.nunique()) uv_hour.head() pv_uv_hour = pd.concat([pv_hour,uv_hour],axis=1) pv_uv_hour.columns = ["pv_hour","uv_hour"] pv_uv_hour.head() # 绘图代码如下 plt.figure(figsize=(16,10)) pv_uv_hour["pv_hour"].plot(c="steelblue",label="每个小时的页面总访问量") plt.ylabel("页面访问量") pv_uv_hour["uv_hour"].plot(c="red",label="每个小时的页面独立访客数",secondary_y=True) plt.ylabel("页面独立访客数") plt.xticks(range(0,24),pv_uv_hour.index) plt.legend(loc="best") plt.grid(True) plt.tight_layout() plt.savefig("每个小时的PV和UV的变化趋势",dpi=300) plt.show() pv_week = clean_data.groupby("week")['user_id'].count() pv_week.head() uv_week = clean_data.groupby("week")['user_id'].apply(lambda x: x.nunique()) uv_week.head() pv_uv_week = pd.concat([pv_hour,uv_hour],axis=1) pv_uv_week.columns = ["pv_hour","uv_hour"] pv_uv_week.head() # 绘图代码如下 plt.figure(figsize=(16,10)) pv_uv_week["pv_hour"].plot(c="steelblue",label="每周的购买次数") plt.ylabel("页面访问量") pv_uv_week["uv_hour"].plot(c="red",label="每周的购买次数",secondary_y=True) plt.ylabel("页面独立访客数") plt.xticks(range(0,7),pv_uv_hour.index) plt.legend(loc="best") plt.grid(True) plt.tight_layout() plt.savefig("每周的PV和UV的变化趋势",dpi=300) plt.show()
四、总结
1.结论:
在RFM模型中,一般发展和一般挽留客户明显高于其他种类用户,这同样符合实际,年龄分布比例都比较均匀,这说明各个年龄段对网购认同度都差不多。从性别来看,女性的数目略微高于男性。
2.收获:
在本次过程中,熟悉并掌握了numpy,pandas还有实现可视化的第三方库的使用,并对RFM模型有了更深入的了解,与此同时,我明白了在当前的社会中,人们每天产生的数据蕴藏着巨大的价值。
标签:分析,plt,pv,hour,data1,销售,电商,data,id From: https://www.cnblogs.com/zhengyihong/p/16995663.html