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

作者:Cherich_sun

来源:杰哥的IT之旅

本篇文章是关于某化妆品企业的销售分析。

从分析思路思路开始带大家一步步的用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()/9

plt.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 = xxticks = np.arange(len(labels))width = 0.5p = 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] = 0        results[i[0]]['口红'] = money

results= {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] - widths        ax.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',color=text_color)    ax.legend(ncol=len(category_names), bbox_to_anchor=(0, 1),              loc='lower left', fontsize='small')

    return fig, axsurvey1(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] = 0
        results[i[0]]['口红'] = money

results= {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] - widths
        ax.barh(labels, widths, left=starts, height=0.5,
                label=colname, color=color)
        xcenters = starts + widths / 2

ax.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 npimport matplotlib.pyplot as pltcategory_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] = 0        results[i[0]]['口红'] = money

results= {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] - widths        ax.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, axsurvey(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_rebuyprint('复购率:',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、从同期群分析来看,新用户明显减少,应考虑拉新,增加平台新用户(主播带货等);

(0)

相关推荐

  • 生命科学中的 UMAP(降维算法)

    UMAP应该说是目前最好的降维算法了,能最大程度的保留原始数据的特征同时大幅度的降低特征维数. 这是<生命科学的数理统计和机器学习>的相关探讨,我试图介绍生物信息学.生物医学.遗传学等常见 ...

  • 数据可视化:疫情期间市值增长top25公司

    数据可视化:疫情期间市值增长top25公司

  • 用matplotlib绘制体重变化十年趋势图

    author: Quantified Bob src: https://www.quantifiedbob.com/body-composition-data-visualization/ 每天看到运 ...

  • 画出这张官方神图,你的Matplotlib就毕业了!

    大家好,我是早起. 在昨天的文章人人都能看懂的Matplotlib绘图原理中,我们对Matplotlib的绘图机制进行了讲解,在弄清楚plt.xxxx和ax.xxxx中plt和ax区别之后,本文继续讲 ...

  • 一次性掌握所有 Python 画图基础操作

    p y t h o n python python 画图介绍 本文以实用为第一目标,保证读者在看完此文之后可以迅速上手 p y t h o n python python 画图,掌握所有画图的基本技巧 ...

  • Python中的Matplotlib绘图

    Matplotlib是Python的绘图工具,用Matplotlib可以绘制出我们想要的各类2D图.Matplotlib可用于python脚本.jupyter notebook.web等.个人认为在J ...

  • 利用python tushare pandas进行财报分析

    一.财报分析 大家在购买股票的时候,已经不只是凭感觉去买了,基本上都会对一个股票进行深入的分析. 毕竟购买股票还是一项风险性较高的投资,需要在较为熟悉以后才能去开展,不能蛮干,钱也都不是天上掉下来的. ...

  • 利用Python实现财务分析/经营分析自动化

    之前写公司研究报告时,所有的数据都是通过翻看招股说明书/年报的PDF获取的,把数字从PDF里复制粘贴到EXCEL里再生成图表的过程非常繁琐,而且容易因为看错行/列摘错数据.使用Python可以实现提取 ...

  • 【利用python进行数据分析——基础篇】利用Python处理和分析Excel表中数据实战

    作为一个学习用Python进行数据分析的新手来说,通过本文来记录分享一些我在用Python中的pandas.numpy来分析Excel表中数据的数据清洗和整理的工作,目的是熟悉numpy以及panda ...

  • 利用python实现微信好友分析(简单)

    一.功能介绍 本文主要介绍利用网页端微信获取数据,实现个人微信好友数据的获取,并进行一些简单的数据分析,功能包括: 1.爬取好友列表,显示好友昵称.性别和地域和签名, 文件保存为 xlsx 格式 2. ...

  • 利用技术分析判断股票趋势的方法

        在股市中有一句话叫做顺势而为,相信无论新老股民都听说过,但是势在何方就不太好说了,判断股票趋势是首要条件,不能判断股票趋势,也就谈不上什么顺势而为了.那么,判断股票趋势的方法有哪些呢?     ...

  • 尊尊网:如何利用成交量分析股票?

    一般来说,成交量放出巨量时,股价往往处在相对高位:成交极度萎缩时,说明股价已跌至相对低位,这对短线操作者寻找买点特别有效.假如某只个股的成交量在一段时间内逐步萎缩,当量无法进一步萎缩时,往往意味着股价 ...

  • 如何利用成交量分析股票?

    首先,股票的成交量是买.卖双方达成成交后就会出现确定成交的单子,在股市交易时间(一个时间单位中)内成交量的单子数量(以每1手为单位).股票成交量在市场中分为放量.缩量.地量等等,因为股票市场是买卖博弈 ...

  • 利用Python绘制关系网络图

    我们在做数据可视化时,要展现多个元素之间的相互关系时(比如人物关系图),常会用到网络图. 今天我们就分享一个在 Python 里绘制网络图的库:NetworkX,并显示它的基本操作. 一.Networ ...

  • (1条消息) 程序员:利用Python实现可控制肉鸡的反向Shell

    一.初识 1.1 用 Python 实现一个可以管理多个肉鸡的反向 Shell,为什么叫反向 Shell 呢?反向就是肉鸡作为 Client 主动连接到我们的 Server 端,以实现对多个远程主机的 ...