利用Python进行数据分析之超市零售分析 |
您所在的位置:网站首页 › 春节超市销售提升方法 › 利用Python进行数据分析之超市零售分析 |
[email protected],Pycharm2019.3.3,Python3.7.7,jupyter notebook
超市零售数据分析
1 背景与需求2 数据收集与整合3 数据清洗4 数据分析及可视化4.1 销售情况分析4.1.1 销售额分析4.1.2 销量分析4.1.3 利润分析4.1.4 客单价分析4.1.5 市场布局分析
4.2 商品情况分析4.2.1 销量前10名的商品4.2.2 销售额前10名的商品4.2.3 利润前10的商品4.2.4 商品种类销售情况
4.3 用户情况分析4.3.1 不同类型的用户占比4.3.2 用户下单行为分析4.3.3 RFM模型分析4.3.4 新用户、活跃用户、不活跃用户和回归用户分析4.3.5 复购率和回购率分析
5 总结6 参考资料
1 背景与需求
本文主要对一家全球超市四年(2011-2014)的销售数据进行销售情况分析、商品情况分析和用户情况分析,并给出提升销量的建议。(本文基于参考资料[2],在其基础上做了进一步的分析,并得出详细的结论) 销售情况分析:销售额、销量、利润、客单价和市场布局等情况分析; 商品情况分析:商品结构、优势商品、劣势/待优化商品等情况分析; 用户情况分析:客户数量、新老客户、RFM模型、复购率和回购率等情况分析。 2 数据收集与整合数据来源于kaggle平台,是一份全球大型超市四年的零售数据集,共有51290条数据,共24个特征。想获取原始数据集,见参考资料。 整合数据: # 加载数据分析需要使用的库 import numpy as np import pandas as pd import matplotlib.pyplot as plt import seaborn as sns import warnings plt.rcParams['font.sans-serif'] = ['SimHei'] warnings.filterwarnings('ignore') #数据加载和整合 # 加载零售数据集,使用'ISO-8859-1'编码方式 df = pd.read_csv('superstore_dataset2011-2015.csv',encoding='ISO-8859-1') df.head() #数据大小 df.shape #数据分布情况 df.describe() 3 数据清洗1)改写不符合规则的列名,统一采用下划线格式 #重命名列名 df.rename(columns = lambda x: x.replace(' ', '_').replace('-', '_'), inplace=True)2)将下单日期改为datetime类型 df["Order_Date"] = pd.to_datetime(df["Order_Date"])3)方便后续的分析,新增加年份列和月份列 df['year'] = df["Order_Date"].dt.year df['month'] = df['Order_Date'].values.astype('datetime64[M]')4)邮编信息一列缺失太多,且对后续分析无影响,直接删除 #查看缺失值 df.isnull().sum(axis=0) #删除邮编信息列 df.drop(["Postal_Code"],axis=1, inplace=True)5)查看有无异常值 #异常值处理 df.describe() #无异常,不需要处理 #重复值处理 df.duplicated().sum() #无重复值,不需要处理 4 数据分析及可视化 4.1 销售情况分析构建销售情况子数据集,并按照年份、月份对销售子数据集进行分组求和。 # 整体销售情况子数据集,包含下单日期、销售额、销量、利润、年份、月份信息 sales_data = df[['Order_Date','Sales','Quantity','Profit','year','month']] #按照年份、月份对销售子数据集进行分组求和 sales_year = sales_data.groupby(['year','month']).sum()部分结果如下: Sales Quantity Profit year month 2011 2011-01-01 138241.30042 2178 13457.23302 2011-02-01 134969.94086 1794 17588.83726 2011-03-01 171455.59372 2183 16169.36062 2011-04-01 128833.47034 2181 13405.46924 2011-05-01 148146.72092 2057 14777.45792 2011-06-01 189338.43966 2715 25932.87796 2011-07-01 162034.69756 2266 10631.84406 2011-08-01 219223.49524 2909 19650.67124 2011-09-01 255237.89698 3357 32313.25458 2011-10-01 204675.07846 2615 30745.54166 2011-11-01 214934.29386 3165 21261.40536 2011-12-01 292359.96752 4023 33006.85862对以上数据进行拆分,每年为一个表 year_2011 = sales_year.loc[(2011,slice(None)),:].reset_index() year_2012 = sales_year.loc[(2012,slice(None)),:].reset_index() year_2013 = sales_year.loc[(2013,slice(None)),:].reset_index() year_2014 = sales_year.loc[(2014,slice(None)),:].reset_index() 4.1.1 销售额分析 #销售额分析 sales=pd.concat([year_2011['Sales'],year_2012['Sales'], year_2013['Sales'],year_2014['Sales']],axis=1) # 对行名和列名进行重命名 sales.columns=['Sales-2011','Sales-2012','Sales-2013','Sales-2014'] sales.index=['Jau','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'] # 颜色越深,销售额越高 sales.style.background_gradient()
计算每年的销售总额及增长率并绘图显示: sales_sum=sales.sum() sales_sum.plot(kind='bar',alpha=0.5) plt.grid() # 计算每年增长率 rise_12=sales_sum[1]/sales_sum[0]-1 rise_13=sales_sum[2]/sales_sum[1]-1 rise_14=sales_sum[3]/sales_sum[2]-1 rise_rate=[0,rise_12,rise_13,rise_14] # 显示增长率 sales_sum=pd.DataFrame({'sales_sum':sales_sum}) sales_sum['rise_rate']=rise_rate从上图可以看出,销售额是逐年递增的,2014的销售额接近于2011年的两倍,说明公司发展势头很好。接着了解每月的销售额情况,用面积图显示 sales.plot.area(stacked=False)
因此,下半年运营推广等策略要继续维持,还可以加大投入,提高整体销售额;而在上半年,可以结合产品特点进行新产品拓展,举办一些促销活动等吸引客户。 4.1.2 销量分析构建销量表并递增显示 #销量分析 quantity = pd.concat([year_2011['Quantity'],year_2012['Quantity'], year_2013['Quantity'],year_2014['Quantity']],axis=1) # 对行名和列名进行重命名 quantity.columns=['Quantity-2011','Quantity-2012','Quantity-2013','Quantity-2014'] quantity.index=['Jau','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'] # 颜色越深,销量越高 quantity.style.background_gradient()计算销量增长率和每年的销量总和 # 计算年度销量并图表展示 quantity_sum=quantity.sum() quantity_sum.plot(kind='bar',alpha=0.5) plt.grid() # 计算每年增长率 rise_12=quantity_sum[1]/quantity_sum[0]-1 rise_13=quantity_sum[2]/quantity_sum[1]-1 rise_14=quantity_sum[3]/quantity_sum[2]-1 rise_rate=[0,rise_12,rise_13,rise_14] # 显示增长率 quantity_sum=pd.DataFrame({'quantity_sum':quantity_sum}) quantity_sum['rise_rate']=rise_rate
构建利润表 profit=pd.concat([year_2011['Profit'],year_2012['Profit'], year_2013['Profit'],year_2014['Profit']],axis=1) profit.columns=['Profit-2011','Profit-2012','Profit-2013','Profit-2014'] profit.index=['Jau','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'] profit.style.background_gradient()结果如下: 计算每年总利润和利润率 profit_sum=profit.sum() profit_sum.plot(kind='bar',alpha=0.5) plt.grid() profit_sum=pd.DataFrame({'profit_sum':profit_sum}) profit_sum["year"] = [2011, 2012, 2013, 2014] sales_sum=pd.DataFrame({'sales_sum':sales.sum()}) sales_sum["year"] = [2011, 2012, 2013, 2014] profit_sum = pd.merge(profit_sum, sales_sum) profit_sum["profit_rate"] = profit_sum["profit_sum"] / profit_sum["sales_sum"]
客单价(per customer transaction)是指商场(超市)每一个顾客平均购买商品的金额,也即是平均交易金额。(百度百科) 客单价的计算公式是:客单价=销售额÷成交顾客数。 > # 2011-2014年客单价 for i in range(2011,2015): data=df[df['year']==i] price=data[['Order_Date','Customer_ID','Sales']] # 计算总消费次数 price_dr=price.drop_duplicates( subset=['Order_Date', 'Customer_ID']) # 总消费次数:有多少行 total_num=price_dr.shape[0] print('{}年总消费次数='.format(i),total_num) unit_price = price['Sales'].sum()/total_num print('{}年客单价='.format(i), unit_price,'\n') ------------------------------------------------------------------------------ 2011年总消费次数= 4453 2011年客单价= 507.3997070604087 2012年总消费次数= 5392 2012年客单价= 496.55762136498515 2013年总消费次数= 6753 2013年客单价= 504.3308824788983 2014年总消费次数= 8696 2014年客单价= 494.4647965225392从输出结果来看,总消费次数呈现逐年递增的趋势,但是客单价保持在500左右不变。 4.1.5 市场布局分析分析不同地区之间的销售情况 Market_Year_Sales = df.groupby(['Market', 'year']).agg({'Sales':'sum'}).reset_index().rename(columns={'Sales':'Sales_amounts'}) Market_Year_Sales.head() sns.barplot(x='Market', y='Sales_amounts', hue='year', data = Market_Year_Sales) plt.title('2011-2014 market sales')
计算各个地区销售额占总销售额的百分比 Market_Sales = df.groupby(['Market']).agg({'Sales':'sum'}) Market_Sales["percent"] = Market_Sales["Sales"] / df["Sales"].sum() Market_Sales.style.background_gradient()
从结果可以看出,销量最高的大部分是办公用品,而销售额最高的大部分是电子产品、家具这些单价较高的商品。 4.2.3 利润前10的商品 productId_Profit= df.groupby('Product_ID').sum()['Profit'].sort_values(ascending=False) print(productId_Profit.head(10)) ------------------------------------ Product_ID TEC-CO-10004722 25199.9280 OFF-AP-10004512 10345.5840 TEC-PH-10004823 8121.4800 OFF-BI-10003527 7753.0390 TEC-CO-10001449 6983.8836 FUR-CH-10002250 6123.2553 TEC-PH-10004664 5455.9482 OFF-AP-10002330 5452.4640 TEC-PH-10000303 5356.8060 FUR-CH-10002203 5003.1000 Name: Profit, dtype: float64利润最高的大部分是电子类产品。 4.2.4 商品种类销售情况 # 根据商品种类和子种类,重新重合成一个新的种类 df['Category_Sub_Category'] = df[['Category','Sub_Category']].apply(lambda x:str(x[0])+'_'+str(x[1]),axis=1) # 按照新的种类进行分组,统计销售额和利润 df_Category_Sub_Category=df.groupby("Category_Sub_Category").agg({"Profit":"sum","Sales":"sum"}).reset_index() # 按照销售额倒序排序 df_Category_Sub_Category.sort_values(by=["Sales"],ascending=False, inplace=True) # 每个种类商品的销售额累计占比 df_Category_Sub_Category['cum_percent'] = df_Category_Sub_Category['Sales'].cumsum()/df_Category_Sub_Category['Sales'].sum() df_Category_Sub_Category
每一年不同类型的用户数量情况 Segment_Year = df.groupby(["Segment", 'year']).agg({'Customer_ID':'count'}).reset_index() sns.barplot(x='Segment', y='Customer_ID', hue='year', data = Segment_Year) plt.title('2011-2014 Segment Customer')
不同类型的用户每年贡献的销售额: Segment_sales = df.groupby(["Segment", 'year']).agg({'Sales':'sum'}).reset_index() sns.barplot(x='Segment', y='Sales', hue='year', data = Segment_sales) plt.title('2011-2014 Segment Sales')
获取新的子数据集 grouped_Customer = df[['Customer_ID','Order_Date', 'Quantity', 'Sales', 'month']].sort_values(['Order_Date']).groupby('Customer_ID') grouped_Customer.head()用户的第一次购买日期分布 grouped_Customer.min().Order_Date.value_counts().plot()
用户的最后一次购买日期分布 grouped_Customer.max().Order_Date.value_counts().plot()
只购买过一次的客户数量 # 统计每个客户第一次和最后一次购买记录 Customer_life = grouped_Customer.Order_Date.agg(['min','max']) # 查看只有一次购买记录的顾客数量,第一次和最后一次是同一条记录,则说明购买只有一次 (Customer_life['min'] == Customer_life['max']).value_counts() ----------------------------------------------------- False 1580 True 10 dtype: int64购买一次的用户只有10位,说明该商家在维持老客方面做得很不错,这也保证了商家的销售额。 4.3.3 RFM模型分析R是指用户的最近一次消费时间,用最通俗的话说就是,用户最后一次下单时间距今天有多长时间了,这个指标与用户流失和复购直接相关。 F是指用户下单频率,通俗一点儿就是,用户在固定的时间段内消费了几次。这个指标反映了用户的消费活跃度。 M是指用户消费金额,其实就是用户在固定的周期内在平台上花了多少钱,直接反映了用户对公司贡献的价值。 而RFM模型就是通过一个客户的近期购买行为、购买的总体频率以及花了多少钱三项指标,来描述该客户的价值状况。
设置Customer_ID为索引,month为列名,统计每个月的购买次数。 pivoted_counts = df.pivot_table(index= 'Customer_ID', columns= 'month', values= 'Order_Date', aggfunc= 'count').fillna(0) # 大于一次的全部设为1 df_purchase = pivoted_counts.applymap(lambda x:1 if x>0 else 0) df_purchase.head()定义状态函数并进行状态标记。 def active_status(data): status = [] for i in range(48): if data[i] == 0: if len(status)>0: if status[i-1] == "unreg": # 未注册客户 status.append("unreg") else: # 不活跃用户 status.append("unactive") else: status.append("unreg") # 若本月消费了 else: if len(status) == 0: # 新用户 status.append("new") else: if status[i-1] == "unactive": # 回归用户 status.append("return") elif status[i-1] == "unreg": status.append("new") else: status.append("active") return pd.Series(status) purchase_stats = df_purchase.apply(active_status,axis =1) purchase_stats.head()结果如下:
复购率计算指标:用户在该月购买过一次以上算复购。 purchase_r = pivoted_counts.applymap(lambda x :1 if x>1 else np.NaN if x==0 else 0) (purchase_r.sum()/purchase_r.count()).plot(figsize=(10,4))回购率计算指标:在该月购买过,且在下月也购买时计入回购。 def purchase_back(data): status=[] for i in range(47): if data[i] ==1: if data[i+1] == 1: status.append(1) if data[i+1] == 0: status.append(0) else: status.append(np.NaN) status.append(np.NaN) return status purchase_b = df_purchase.apply(purchase_back,axis =1,result_type='expand') (purchase_b.sum()/purchase_b.count()).plot(figsize=(10,4))从上可以发现复购率基本大于0.52,且呈总体上升趋势,说明客户忠诚度高,也和之前分析的商家维持老客做得很好相对应;回购率在年中年末呈峰形态,可能与商家折扣活动或节日有关,间接也说明活动或节日起到了一定的影响力。 5 总结1)从销售情况分析来看,每年下半年的销售额、销量和利润均是明显好于上半年,且均逐年递增;从输出结果来看,总消费次数呈现逐年递增的趋势,但是客单价保持在500左右不变;不管在哪个地区,销售额呈现逐年递增的趋势。 2)从商品情况分析来看,销量最高的大部分是办公用品,电子产品的销售额最高而且利润最大,所以商家可以持续发展在电子产品类的利润优势,但是Tables(桌子)的利润是负的,需要保持关注,收集更多数据去了解和确定产生负利润的原因。 3)从用户情况分析来看,不管是哪种类型的用户,其数量和销售额每年都是呈现一个递增的趋势;该商家在维持老客方面做得很不错,但是2013年初后,新客增长趋势缓慢,商家需要通过广告、活动等方式吸引更多的新客。 6 参考资料1、原始数据集 链接:https://pan.baidu.com/s/13QNHG7sRZu4iwcJ4Sz9F1g 提取码:ec7j 2、数据分析实战之超市零售分析 3、RFM模型 4、python 数据表格的合并和重塑 |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |