作者:Cherich_sun
来源:公众号「杰哥的IT之旅」ID:Jake_Internet

【导语】本篇文章是关于某化妆品企业的销售分析。从分析思路思路开始带大家一步步的用python进行分析,找出问题,并提出解决方案的整个流程。

需求:希望全面了解此某妆品企业的销售情况,帮助企业运营领导层了解企业整体销售运营情况及商品销售情况,为该企业的营销策略提供相对应的建议和销售策略。

业务分析流程

1、 场景(诊断现状)

对象:用户;销售
关注点:找到影响销售的增长因素
目标:发现问题&提出解决方案

2、需求拆解

分析销售趋势,找到影响企业营收增长的商品或区域

按月份销售趋势图(整体)
商品销售额对比(一级、二级,找出最低、最高)
区域销售额对比(下钻:区、省,找出最低、最高)

探索不同商品的销售状况,为企业的商品销售,提出策略建议

不同月份的各个产品的销售额占比情况
产品相关分析

分析用户特征、购买频率、留存率等

购买频率分布
复购率(重复购买用户数量(两天都有购买过算重复)/用户数量)
同期群分析(按月)

3、代码实现

获取数据(excel)

为某化妆品企业 2019 年 1 月-2019 年 9 月每日订单详情数据和企业的商品信息数据,包括两个数据表,销售订单表和商品信息表。其中销售订单表为每个订单的情况明细,一个订单对应一次销售、一个订单可包含多个商品。

import pandas as pd
import matplotlib.pyplot as plt
import matplotlib as mpl
mpl.rcParams['font.family'] = 'SimHei'
import numpy as np
import warnings
warnings.filterwarnings("ignore")
data = pd.read_excel('C:/Users/cherich/Desktop/日化.xlsx',encoding='gbk')
data.head()

data_info = pd.read_excel('C:/Users/cherich/Desktop/日化.xlsx',encoding='gbk',sheet_name='商品信息表')
data_info

数据清洗和加工

data = data.dropna()
# 订购数量结尾有字符'个'data['订购数量'] = data['订购数量'].apply(lambda x:str(x)[:-1] if str(x)[-1] == '个' else x)
data['订购数量'] = data['订购数量'].astype(int)# 订购数量结尾有字符'元'
data['订购单价'] = data['订购单价'].apply(lambda x:str(x)[:-1] if str(x)[-1] == '元' else x)
data['订购单价'] = data['订购单价'].astype(int)
# 日期里有特殊字符 2019#3#11
def proess_date(df):pos = str(df).find('#')if pos!= -1:df = str(df).split('#')return df[0]+'-'+df[1]+'-'+df[2]else:return df# res = proess_date(df ='2019#3#11')
data['订单日期'] = data['订单日期'].apply(proess_date)
data['订单日期'] = data['订单日期'].apply(lambda x:str(x).replace('年','-').replace('月','-') if '年' in str(x) else x )
data['订单日期'] = pd.to_datetime(data['订单日期'])
#data.info()data = data[data.duplicated()==False]
data['所在省份'].nunique()
data['月份'] = data['订单日期'].apply(lambda x:str(x).split('-')[1])
data

数据可视化

# 两张表数据合并
total_data = pd.merge(data,data_info,on='商品编号',how='left')
total_data

groups = data.groupby('月份')
x = [each[0] for each in groups]
y = [each[1].金额.sum() for each in groups]
z = [each[1].金额.count() for each in groups]
money_mean = data.金额.sum()/9
order_mean = data.金额.count()/9plt.figure(figsize=(18, 10), dpi=80)
plt.subplot(221)
plt.plot(x, y,linewidth=2)
plt.axvspan('07', '08', color='#EE7621', alpha=0.3)
plt.axhline(money_mean, color='#EE7621', linestyle='--',linewidth=1)
plt.title("每月销售额趋势图",color='#4A708B',fontsize=24)
plt.ylabel("金额/(亿)",fontsize=16)plt.subplot(222)
plt.plot(x, z, linewidth=2, color = '#EE7621')
plt.axvline('07', color='#4A708B', linestyle='--',linewidth=1)
plt.axhline(order_mean, color='#4A708B', linestyle='--',linewidth=1)
plt.title("每月订单量趋势图",color='#4A708B',fontsize=24)
plt.ylabel("订单/(单)",fontsize=16)
plt.show()

图表说明:从整体来看,销售额和订单量从4月开始大幅度上升,均高于均值;8月份开始呈下降趋势,处于均值水平。

groups_category= total_data.groupby(['月份','商品大类'])
category1 = []
category2 = []
for i,j in groups_category:
#     print(i,j.月份.count())if i[1]=='彩妆':category1.append(j.金额.sum())else:category2.append(j.金额.sum())
labels = x
xticks = np.arange(len(labels))
width = 0.5
p = np.arange(len(labels))
fig, ax = plt.subplots(figsize=(18,8))
rects1 = ax.bar(p - width/2, category1,width, label='彩妆',color='#FFEC8B')
rects2 = ax.bar(p + width/2, category2, width, label='护肤品',color='#4A708B')ax.set_ylabel('销售额/(亿)')
ax.set_title('每月护肤品和彩妆的销售额对比图(大类)')
ax.set_xticks(xticks)
ax.set_xticklabels(labels)
ax.legend()plt.show()

图表说明:护肤品需求满足大多数人,明显高于彩妆。并且5月—8月是护肤品需求旺季。相比彩妆的变化不明显。

groups_categorys= total_data.groupby('商品小类')
x = [each[0] for each in groups_categorys]
y = [each[1].金额.sum() for each in groups_categorys]fig = plt.figure(figsize=(18,8),dpi=80)
plt.title('各个品类的销售额对比图',color='#4A708B',fontsize=24)
plt.ylabel('销售额(元)',fontsize=15)
colors = ['#6699cc','#4A708B','#CDCD00','#DAA520','#EE7621','#FFEC8B','#CDCD00','#4A708B','#6699cc','#DAA520','#4A708B','#FFEC8B']
for i, group_name in enumerate(groups_categorys):lin1 =plt.bar(group_name[0], group_name[1].金额.sum(),width=0.8,color=colors[i])for rect in lin1:height = rect.get_height()plt.text(rect.get_x()+rect.get_width()/2, height+1, int(height),ha="center",fontsize=12)plt.xticks(fontsize=15)
plt.grid()
plt.show()

图表说明:面膜的销售额第一,其次是面霜、爽肤水。销售额最低的是蜜粉,眼影。

total_data = total_data.dropna()
total_data['所在区域'] = total_data['所在区域'].apply(lambda x:str(x).replace('男区','南区').replace('西 区','西区'))
groups_area= total_data.groupby(['所在区域','商品小类'])
results = {}
for i,j  in groups_area: money = int(j.金额.sum())if i[0] in results.keys():results[i[0]][i[1]] = money     else:results[i[0]] = {}   for cate in category_names:results[i[0]][cate] = 0results[i[0]]['口红'] = moneyresults= {key_data:list(values_data.values()) for key_data,values_data in results.items()}def survey1(results, category_names):labels = list(results.keys())data = np.array(list(results.values()))data_cum = data.cumsum(axis=1)category_colors = plt.get_cmap('RdYlGn')(np.linspace(0.15, 0.85, data.shape[1]))fig, ax = plt.subplots(figsize=(25,8))ax.invert_yaxis()ax.xaxis.set_visible(False)ax.set_xlim(0, np.sum(data, axis=1).max())for i, (colname, color) in enumerate(zip(category_names, category_colors)):widths = data[:, i]starts = data_cum[:, i] - widthsax.barh(labels, widths, left=starts, height=0.5,label=colname, color=color)xcenters = starts + widths / 2r, g, b, _ = colortext_color = 'white' if r * g * b < 0.5 else 'darkgrey'for y, (x, c) in enumerate(zip(xcenters, widths)):ax.text(x, y, str(int(c)), ha='center', va='center',color=text_color)ax.legend(ncol=len(category_names), bbox_to_anchor=(0, 1),loc='lower left', fontsize='small')return fig, ax
survey1(results, category_names)
plt.show()

图表说明:东部地区占市场份额的35%左右,份额最低的是西部地区。

area_names = list(total_data.商品小类.unique())
groups_priv= total_data.groupby(['所在省份','商品小类'])
results = {}
for i,j  in groups_priv: money = int(j.金额.sum())if i[0] in results.keys():results[i[0]][i[1]] = money     else:results[i[0]] = {}   for cate in category_names:results[i[0]][cate] = 0results[i[0]]['口红'] = moneyresults= {key_data:list(values_data.values()) for key_data,values_data in results.items()}def survey2(results, category_names):labels = list(results.keys())data = np.array(list(results.values()))data_cum = data.cumsum(axis=1)category_colors = plt.get_cmap('RdYlGn')(np.linspace(0.15, 0.85, data.shape[1]))fig, ax = plt.subplots(figsize=(25,20))ax.invert_yaxis()ax.xaxis.set_visible(False)ax.set_xlim(0, np.sum(data, axis=1).max())for i, (colname, color) in enumerate(zip(category_names, category_colors)):widths = data[:, i]starts = data_cum[:, i] - widthsax.barh(labels, widths, left=starts, height=0.5,label=colname, color=color)xcenters = starts + widths / 2ax.legend(ncol=len(category_names), bbox_to_anchor=(0, 1),loc='lower left', fontsize='small')return fig, ax
survey2(results, area_names)
plt.show()

图表说明:江苏销售额第一,其次是广东省;销售额最低的是宁夏、内蒙、海南

import numpy as np
import matplotlib.pyplot as plt
category_names = list(total_data.商品小类.unique())
groups_small_category= total_data.groupby(['月份','商品小类'])
results = {}
for i,j  in groups_small_category: money = int(j.金额.sum())if i[0] in results.keys():results[i[0]][i[1]] = money     else:results[i[0]] = {}   for cate in category_names:results[i[0]][cate] = 0results[i[0]]['口红'] = moneyresults= {key_data:list(values_data.values()) for key_data,values_data in results.items()}
def survey(results, category_names):labels = list(results.keys())data = np.array(list(results.values()))data_cum = data.cumsum(axis=1)category_colors = plt.get_cmap('RdYlGn')(np.linspace(0.15, 0.85, data.shape[1]))fig, ax = plt.subplots(figsize=(25,8))ax.invert_yaxis()ax.xaxis.set_visible(False)ax.set_xlim(0, np.sum(data, axis=1).max())for i, (colname, color) in enumerate(zip(category_names, category_colors)):widths = data[:, i]starts = data_cum[:, i] - widthsax.barh(labels, widths, left=starts, height=0.5,label=colname, color=color)xcenters = starts + widths / 2#         r, g, b, _ = color
#         text_color = 'white' if r * g * b < 0.5 else 'darkgrey'
#         for y, (x, c) in enumerate(zip(xcenters, widths)):
#             ax.text(x, y, str(int(c)), ha='center', va='center')ax.legend(ncol=len(category_names), bbox_to_anchor=(0, 1),loc='lower left', fontsize='small')return fig, ax
survey(results, category_names)plt.show()

图表说明:眼霜、爽肤水、面膜:4,5,6,7,8月份需求量最大;粉底、防晒霜、隔离霜、睫毛膏、蜜粉1,2,3月份需求量最大。

data_user_buy=total_data.groupby('客户编码')['订单编码'].count()
data_user_buy
plt.figure(figsize=(10,4),dpi=80)
plt.hist(data_user_buy,color='#FFEC8B')plt.title('用户购买次数分布',fontsize=16)
plt.xlabel('购买次数')
plt.ylabel('用户数')
plt.show()

图表说明:大部分用户购买次数在10次-35次之间,极少部分用户购买次数80次以上

date_rebuy=total_data.groupby('客户编码')['订单日期'].apply(lambda x:len(x.unique())).rename('rebuy_count')
date_rebuy
print('复购率:',round(date_rebuy[date_rebuy>=2].count()/date_rebuy.count(),4))

total_data['时间标签'] = total_data['订单日期'].astype(str).str[:7]
total_data = total_data[total_data['时间标签']!='2050-06']
total_data['时间标签'].value_counts().sort_index()
total_data = total_data.sort_values(by='时间标签')
month_lst = total_data['时间标签'].unique()
final=pd.DataFrame()
final
#引入时间标签
for i in range(len(month_lst)-1):#构造和月份一样长的列表,方便后续格式统一count = [0] * len(month_lst)#筛选出当月订单,并按客户昵称分组target_month = total_data.loc[total_data['时间标签']==month_lst[i],:]target_users = target_month.groupby('客户编码')['金额'].sum().reset_index()#如果是第一个月份,则跳过(因为不需要和历史数据验证是否为新增客户)if i==0:new_target_users = target_month.groupby('客户编码')['金额'].sum().reset_index()else:#如果不是,找到之前的历史订单history = total_data.loc[total_data['时间标签'].isin(month_lst[:i]),:]#筛选出未在历史订单出现过的新增客户new_target_users = target_users.loc[target_users['客户编码'].isin(history['客户编码']) == False,:]#当月新增客户数放在第一个值中count[0] = len(new_target_users)#以月为单位,循环遍历,计算留存情况for j,ct in zip(range(i + 1,len(month_lst)),range(1,len(month_lst))):#下一个月的订单next_month = total_data.loc[total_data['时间标签'] == month_lst[j],:]next_users = next_month.groupby('客户编码')['金额'].sum().reset_index()#计算在该月仍然留存的客户数量isin = new_target_users['客户编码'].isin(next_users['客户编码']).sum()count[ct] = isin#格式转置result = pd.DataFrame({month_lst[i]:count}).T#合并final = pd.concat([final,result])final.columns = ['当月新增','+1月','+2月','+3月','+4月','+5月','+6月','+7月','+8月']
result = final.divide(final['当月新增'],axis=0).iloc[:]
result['当月新增'] = final['当月新增']
result.round(2)

同期群分析

图表说明:由新增用户情况看,新用户逐月明显减少;留存率在1月-5月平均在50%,6月-8月留存率上升明显。

结论与建议

1、从销售额趋势来看,整体是上升趋势,但是从8月份销售额突然下降,可能因为到淡季,需进一步确认原因;

2、商品销售额,用户对护肤品具有强烈的需求,尤其是面膜,爽肤水、面霜、眼霜。较低需求的是蜜粉。可以把高需求产品,组合成礼盒等套装活动;

3、商品销售建议:眼霜、爽肤水、面膜:4,5,6,7,8月需求最大;粉底、防晒霜、隔离霜、睫毛膏、蜜粉1,2,3月需求最大。以上说明用户购买特定产品具有周期性;

4、从地域来看,东部地区是消费的主力军,其中江苏省、广东省、浙江省的销售额最大。可以增大市场投放量;也可以考虑在该地区建仓,节省物流等成本;

5、用户:重点维护购买次数在10次-35次之间的用户群体;

6、留存率在99%,证明用户对产品有一定的依赖性;

7、从同期群分析来看,新用户明显减少,应考虑拉新,增加平台新用户(主播带货等);

推荐阅读
误执行了rm -fr /*之后,除了跑路还能怎么办?!程序员必备58个网站汇总大幅提高生产力:你需要了解的十大Jupyter Lab插件

利用 Python 分析了某化妆品企业的销售情况,我得出的结论是?相关推荐

  1. 利用Python分析航空公司客户价值

      利用Python分析航空公司客户价值 一.背景介绍 随着社会生活中数据量的急剧增多,如何从这些海量的数据中提取与发掘出对我们决策有用的信息成为当前亟待解决的题,因此,数据分析与挖掘技术在这些年得到 ...

  2. 利用Python分析《庆余年》人物图谱和微博传播路径

    利用Python分析<庆余年>人物图谱和微博传播路径 庆余年电视剧终于在前两天上了,这两天赶紧爬取微博数据看一下它的表现. 庆余年 <庆余年>是作家猫腻的小说.这部从2007年 ...

  3. 利用Python分析文章词频,并生成词云图

    利用Python分析文章词频,并生成词云图 使用request模块获取文章数据 import jieba import requests import csv from bs4 import Beau ...

  4. 数据分析作业(一)利用Python分析学生成绩

    利用Python分析学生成绩 一.题目描述 二.解题步骤 运行环境 题目分析 三.完整代码 四.运行结果 五.参考文献 附录 附录A 更新记录 附录B 相关练习题目 练习一:读取Excel文件数据表分 ...

  5. python单词软件哪个好_利用Python分析背单词软件的惊人真相

    摘要:利用python分析背单词软件,揭秘你不知道的惊人真相 0×00 前言 你想知道背单词软件有大概多少人注册第一天都没有背完嘛 你想知道背单词软件这么火,这么多人在使用,真的有多少人真的在背诵嘛 ...

  6. 利用python分析电商_Python实现爬取并分析电商评论

    现如今各种APP.微信订阅号.微博.购物网站等网站都允许用户发表一些个人看法.意见.态度.评价.立场等信息.针对这些数据,我们可以利用情感分析技术对其进行分析,总结出大量的有价值信息.例如对商品评论的 ...

  7. ppt python 图表_利用python分析weibo数据做成图表放入PPT中

    起因 很久以前,就有个想法,就是自动分析微博的数据,但是之前一直想的是网页版展示,flask想学了好久都没学,偶然的一次看到了一篇关于python处理pptx的文章,再加上同窗三年的室友在毕业后竟然主 ...

  8. python录入数据至ppt_利用python分析weibo数据做成图表放入PPT中

    起因 很久以前,就有个想法,就是自动分析微博的数据,但是之前一直想的是网页版展示,flask想学了好久都没学,偶然的一次看到了一篇关于python处理pptx的文章,再加上同窗三年的室友在毕业后竟然主 ...

  9. python财务报表分析-浅谈利用Python分析财报找到值得投资的好公司的想法

    17年12月份接触到了007战友林晓燕老师的不读财报不出局,才知道投资股票还有那么多门道,也了解到了MJ老师挑选股票的标准--五大关键数字力. 跟着林老师开始学习财报以来,老是觉得光靠人工来挑选符合& ...

最新文章

  1. C语言中的字符串处理
  2. Python爬取B站5000条视频,揭秘为何千万人为它流泪
  3. 轮子一定要是圆的吗?
  4. 阿里云首次在ASPLOS'19发布重磅论文:揭秘帮助ECS快速迭代的热升级技术
  5. 崛起于Springboot2.X之Mongodb多数据源处理(35)
  6. [vscode] convert tabs to spaces
  7. oracle安装后再建库,oracle-数据库的安装与建库
  8. 高校应该使用 Drupal 的10大理由
  9. php获取最后一条记录的id,获取MySQL的表中每个userid最后一条记录的方法_MySQL
  10. Spring Security 5
  11. 在IBM AIX p750小机上为Oracle扩展逻辑卷-视频分享
  12. Surface设备完美安装Linux/Archlinux双系统教程
  13. IT常用职位缩写总结
  14. kafka中topic默认属性_Kafka的Topic配置详解
  15. mac book pro 安装网络准入后经常死机
  16. 小酷智慧地图3D导览v1.0.87打卡定位 地图打卡
  17. 使用node连接MongoDB的工具安装及配置
  18. 【DirectX11】【学习笔记(4)】顶点索引
  19. 无论你英语多差,只要想学,看了此文必有改变
  20. 选队长游戏(Java)

热门文章

  1. Django - 网页加载报错:A server error occurred. Please contact the administrator(亲测)
  2. nginx整合php+lua+oracle环境搭建
  3. CSS使用display:incline与float:left的区别:脱离文档流 参差不齐
  4. Golang.org不能访问解决方法
  5. Linux之centos镜像
  6. stm32中spi可以随便接吗_stm32之SPI通信协议实例详解
  7. geojson在线生成工具_logofree详解:LOGO设计在线生成
  8. 广西大学计算机专业研究生录取分数线,广西大学电子信息(专硕)专业考研录取分数线-研究生分数线-历年分数线...
  9. 第二章java编程基础测试题_Java编程基础测试题分享
  10. centos7 tomcat_centos7中利用logrotate工具切割日志,以tomcat日志为例