目錄
一、項目背景
二、字段說明
三、資料處理
1.導入庫
2.讀取資料
3.檢視資料
4.異常值處理
5.銷量分析
5.1.各年度銷售情況
5.2.各年份的每月銷量情況
5.3.春節前30日銷售情況走勢
5.4.春節前30日-前13日銷量情況比較
6.原因拆解
7.推廣計劃
7.1.确定推廣時限
7.2.确定資源配置設定
8.總結
一、項目背景
本次樣本資料集來自電商銷售資料資訊,包含從2012年起至2015年2月的兩個表trade(商品交易記錄)和babyinfo(嬰兒資訊)。根據往年同期的銷售資料分析2015年(當年)整體的銷量斷崖式下降的原因,并提出改進方案。
二、字段說明
1. trade表(商品交易記錄):
buy_mount (購買數量/銷量)
user_id(使用者id)
auction_id(購買行為編号)
cat1(商品所屬的大類)
cat_id(cat1的子類,是更細分的類别)
property(商品屬性)
day(購買時間)
2. babyinfo表(嬰兒資訊):
user_id(使用者id)
birthday(出生日期)
gender:性别(0 男孩,1 女孩,2性别不明)
三、資料處理
1.導入庫
import pandas as pd
import numpy as np
from pandas import DataFrame,Series
import os
from matplotlib import pyplot as plt
import seaborn as sns
plt.rcParams['font.sans-serif'] =['Microsoft YaHei'] # 用來正常顯示中文标簽
plt.rcParams['axes.unicode_minus']=False # 用來正常顯示負号
import warnings
warnings.filterwarnings('ignore')
2.讀取資料
df_baby=pd.read_csv('(sample)sam_tianchi_mum_baby.csv')
df_trade=pd.read_csv('(sample)sam_tianchi_mum_baby_trade_history.csv')
3.檢視資料
檢視嬰兒資訊
df_baby.head()
檢視交易資訊
df_trade.head()
可知property有null值
檢視交易資訊
df_trade.describe()
銷量buy_mount的方差有63.9,需要處理
df_trade.isna().sum()
property共有144個null值
對df_trande和df_baby進行連接配接,生成df
df=pd.merge(df_trade,df_baby,left_on='user_id',right_on='user_id',how='left')
df.head()
并對day進行時間格式處理
df['day']=pd.to_datetime(df['day'],format='%Y%m%d')
df.head()
4.異常值處理
對銷量buy_mout銷量字段進行異常值處理。檢視buy_mount資料,對其進行描述性統計
df['buy_mount'].describe()
可知,buy_mount銷量資料有異常值,方差為63.9
檢視buy_mount的資料分布
df.buy_mount.value_counts().sort_index()
print(df.buy_mount.value_counts().sort_index().index)
print(df.buy_mount.value_counts().sort_index().values)
可知,銷量buy_mout在1-15之間的出現次數較高。
根據三倍标準差計算異常值為2.5+3x63.9=194。從業務角度上,根據國雙2018年本土嬰幼兒奶粉電商消費研究的資料,在電商平台購買嬰幼兒奶粉的消費者年均購買次數約為27次,向上取整後,以單筆銷量超過30罐奶粉作異常值處理。
df=df[df['buy_mount']<=30]
df.describe()
5.銷量分析
确認名額:2015年當月銷量同比增速必須高于上年同期同比增速或上年整體同比增速。
分析如下:
- 1 觀察各年度每月銷量情況走勢
- 2 2015年1-2月的銷量走勢對比13年和14年,判斷銷量的好或差?
- 3 如果銷量差,問題出在什麼地方
- 4 如果銷量差,還有多少缺口,有多少時間挽救,重要的挽救時間節點是什麼時候?
- 5 如果要沖銷量,推廣什麼品類?
5.1.各年度銷售情況
以購買日期為标準對資料進行分組聚合,并對時間進行降采樣至月。分别提取每年各月的銷售資料
df.set_index(df.day,inplace=True,drop=True)
df.drop(columns='day',inplace=True)
df_month=df.resample('m').sum()
df_month.drop(columns=['user_id','auction_id','cat_id','cat1','birthday','gender'],inplace=True)
df_month['year']=df_month.index.year
df_month['month']=df_month.index.month
df_month.head()
計算每年的銷量同比增長
df_month.groupby(by='year')['buy_mount'].sum()
df_month.groupby(by='year')['buy_mount'].sum().pct_change()
可知,2014年銷量比2013年增長50.54%。而2015年至今銷量同比增速遠低于目标的50.54%,需要提高至50.54%以上。
5.2.各年份的每月銷量情況
df_month_2012=df_month[df_month['year']==2012]
df_month_2013=df_month[df_month['year']==2013]
df_month_2014=df_month[df_month['year']==2014]
df_month_2015=df_month[df_month['year']==2015]
plt.figure(figsize=[10,8])
plt.plot(df_month_2012['month'],df_month_2012['buy_mount'],label='2012')
plt.plot(df_month_2013['month'],df_month_2013['buy_mount'],label='2013')
plt.plot(df_month_2014['month'],df_month_2014['buy_mount'],label='2014')
plt.plot(df_month_2015['month'],df_month_2015['buy_mount'],label='2015')
plt.xlabel('月份')
plt.ylabel('銷量')
plt.legend(loc='upper left')
plt.title('各年份的每月銷量情況')
plt.show()
可知2013年和2014的走勢相似,1-2月份銷量均出現下降,但并沒有持續下降,在三月份出現上升。是以需要聚焦到1-2月份的資料上進行分析。由于近三年都是在1-2月份銷量下降,可能是由于春節假期。
- 2013年春節:2月9日-2月15日
- 2014年春節:1月30日-2月6日
- 2015年春節:2月19日-2月25日
2015年月2013年相似,春節都完整分布在2月份,是以2015年2月份的資料應該與2013年相似,不能和2014年一樣把銷量都定為同比增長50%。是以将目标時間都改為春節前三十天,分析該段時間的銷量情況比較合理。
5.3.春節前30日銷售情況走勢
df_spring=df.groupby(by=df.index).sum().drop(columns=['user_id','auction_id','cat_id','cat1','birthday','gender'])
df_spring_2013=df_spring['2013-1-10':'2013-2-15']
df_spring_2014=df_spring['2014-1-1':'2014-2-6']
df_spring_2015=df_spring['2015-1':'2015-2'][:-17:-1][::-1] #2015-01-21 至 2015-02-05
x_values=[i for i in range(len(df_spring_2013))]
x_labels=['閏月初一', '閏月初二', '閏月初三', '閏月初四', '閏月初五', '閏月初六', '閏月初七', '閏月初八', '閏月初九', '閏月初十', '閏月十一', '閏月十二', '閏月十三', '閏月十四', '閏月十五', '閏月十六', '閏月十七', '閏月十八', '閏月十九', '閏月二十', '閏月廿一', '閏月廿二', '閏月廿三', '閏月廿四', '閏月廿五', '閏月廿六', '閏月廿七', '閏月廿八', '閏月廿九', '閏月三十', '正月初一', '正月初二', '正月初三', '正月初四', '正月初五', '正月初六', '正月初七']
plt.figure(figsize=(12,8))
plt.plot(x_values,df_spring_2013.buy_mount,label='2013')
plt.plot(x_values,df_spring_2014.buy_mount,label='2014')
plt.plot(x_values[:len(df_spring_2015)],df_spring_2015.buy_mount,label='2015')
plt.legend(loc='best')
plt.xticks(ticks=x_values,labels=x_labels,rotation=60)
plt.xlabel('日期',fontsize=16)
plt.ylabel('銷量',fontsize=16)
plt.title('春節前30日每日銷量情況比較')
plt.show()
5.4.春節前30日-前13日銷量情況比較
df_spring=pd.DataFrame({'2013':df_spring_2013[:16].buy_mount.sum(),'2014':df_spring_2014[:16].buy_mount.sum(),'2015':df_spring_2015.buy_mount.sum()},index=['銷量'])
df_spring_rate=df_spring.pct_change(axis=1)
df_spring_rate.index=['同比增速']
# df_spring,df_spring_rate
df_1=pd.concat([df_spring,round(df_spring_rate*100,2)])
df_1
# pd.concat(df_spring,df_spring_rate)
fig=plt.figure(figsize=[12,8])
ax1=fig.add_subplot(121)
plt.bar(df_1.columns,df_1.loc['銷量'],label='銷量')
for m,n in zip(df_1.columns,df_1.loc['銷量']):
plt.text(m,n+20,n,ha='center')
ax1.set_xlabel('年份')
ax1.set_ylabel('銷量')
plt.title('2013-2015年閏月初一到十五銷量同比情況')
plt.legend(loc='upper left')
#plt.legend(loc='upper left')
ax2=ax1.twinx()
df_2=df_1.loc['同比增速']
plt.plot(df_2.index,df_2,'r',label='同比增速')
for i,j in zip(df_2[1:].index,df_2[1:].values):
plt.text(i,j,j,ha='left')
ax2.set_ylabel('同比增速')
plt.legend(bbox_to_anchor=(0,0.96),loc='upper left')
plt.show()
2014年閏月初一到十五同比增速49.9%,而2015的同比增速是43.24%,小于目标值49.9%,是以2015的銷量狀況并不好。
6.原因拆解
進一步分析是哪款産品導緻的2015年銷量未達标。對2014、2015年的産品按商品大類、年份進行分組求和,分析春節前30-14日各分類銷量情況。
df_reason=df.groupby([df.index,df.cat1]).sum()['buy_mount']
df_reason_2014=df_reason.loc['2014-1-1':'2014-1-16'].unstack()
df_reason_2015=df_reason.loc['2015-1-21':].unstack()
df_reason=pd.DataFrame({'2014':df_reason_2014.sum(),'2015':df_reason_2015.sum()},index=df_reason_2014.columns)
df_reason
df_reason_rate=round(df_reason.pct_change(axis=1)*100,2)['2015']
df_reason_rate
width=0.35
fig=plt.figure(figsize=[16,6])
ax1=fig.add_subplot(121)
plt.bar(np.arange(df_reason.shape[0])-width/2,df_reason['2014'],width,data=df_reason,label='2014年銷量(左軸)')
plt.bar(np.arange(df_reason.shape[0])+width/2,df_reason['2015'],width,data=df_reason,label='2015年銷量(左軸)')
plt.xlabel('産品大類')
plt.ylabel('銷量')
plt.title('2014-2015年春節前30-14日各分類銷量情況')
plt.legend(loc='upper right')
ax2=ax1.twinx()
plt.plot(range(len(df_reason_rate)),df_reason_rate.values,'r',label='同比增速(右軸)')
for i,j in zip(range(len(df_reason_rate)),df_reason_rate.values):
plt.text(i,j+1,j,ha='left')
plt.legend(bbox_to_anchor=(1,0.89),loc='upper right')
plt.xticks(range(len(df_reason_rate)),df_reason.index,rotation=60)
plt.show()
可知,50008168大類、50014815大類都是增長幅度非常的低,是主要的問題點。而122650008大類的增速接近目标值,且銷量占比低,是次要的問題點。
7.推廣計劃
由于沒有更多的資料,針對以上問題,可以對今年2015年未來14天的走勢做基本的預測,發現可提升銷量的機會
7.1.确定推廣時限
對比往年的銷量情況,接下來的銷量會逐漸降低,需要在接下來的一周做推廣計劃
7.2.确定資源配置設定
對不同類别的産品檢視銷售曲線
df_plan=df.groupby([df.index,df.cat1]).sum()['buy_mount']
df_plan_2013=df_plan.loc['2013-1-10':'2013-2-15'].unstack()
df_plan_2014=df_plan.loc['2014-1-1':'2014-2-6'].unstack()
df_plan_2015=df_plan.loc['2015-1-21':].unstack()
df_plan_2013
plt.figure(figsize=[16,12])
for i in range(df_plan_2015.shape[1]):
plt.subplot(3,2,i+1)
plt.plot(range(df_plan_2013.shape[0]),df_plan_2013.iloc[:,i],label='2013')
plt.plot(range(df_plan_2014.shape[0]),df_plan_2014.iloc[:,i],label='2014')
plt.plot(range(df_plan_2015.shape[0]),df_plan_2015.iloc[:,i],label='2015')
plt.legend(loc='best')
plt.grid()
plt.title(f'{df_plan_2013.columns[i]}大類銷量情況')
plt.show()
建議:
28大類:2014年的資料當中,銷量會有明顯的波動周期,隔7-10天會出現一次陡增,需要對比推廣計劃,确定是活動推廣周期還是自然增長。
- 如果為自然增長,未來還會出現1-2次的陡增,單日銷量估計在30左右。
- 如果為活動推廣所緻,參考15年閏月初七至初九。在未來一周内進行一次同類推廣活動,對資料監控後再作下一步推廣計劃
- 作為今年銷量最高的大類,可以選擇其為推廣計劃中的核心産品
38大類:2013-2015銷量資料都不是很穩定,但2015年有個别日期銷量猛增,同樣結合今年的推廣計劃,反推推廣是否能夠促進38大類的銷量。如果有效,可嘗試增加一定推廣的期限。
168大類和815大類:根據過往資料,直到春節結束,銷量會一直下降。參考過往這段時間是否有采取過推廣計劃。如果經過推廣後依舊沒有銷量的增長,那麼有富餘資源的情況下再考慮推廣這兩類。
520大類:520大類在14年的年初六有大幅的增長外,其餘時間兩大類的銷量都是非常的低,可以考慮參考14年的年初六進行一次小規模推廣。
08大類:銷量隻有個位數,很低。結合過往推廣計劃進行判斷,如果已經進行過推廣,但銷量依舊不樂觀,則今年可以放棄08大類,不作推廣。
8.總結
- 現狀:2015年春節前30日-16日同比增速為43.2%,略低于目标的50.54%,銷售狀況有待提高。
- 問題:距離春節還有14天,有504罐的銷量缺口,未來一周日均需要銷售57罐,年廿四到年三十日均銷量需15罐才能達到目标。
- 原因:168、815兩個大類增速遠低于目标值是核心原因,需要收集管道等資料才能進一步定位更具體的原因
- 做法:
- 一周内做1-2論推廣計劃,年廿四或廿五作最後一波沖刺
- 28大類可作為主推産品
- 其次優先推廣38大類、520大類
- 在資源有剩餘的情況下,再考慮推廣168大類、815大類及08大類