時間:2023-03-15 23:36:01 | 來源:電子商務(wù)
時間:2023-03-15 23:36:01 來源:電子商務(wù)
一,背景import pandas as pd data= pd.read_csv('./dataset2011-2015.csv',encoding='ISO-8859-1')print('源數(shù)據(jù)的形狀為:',data.shape)print('查看數(shù)據(jù)的類型:',data.dtypes)print('初步判斷數(shù)據(jù)是否有缺失值:',data. info())print(data.head())使用read_csv讀取數(shù)據(jù)的時候,需要根據(jù)csv文件存儲時的編碼格式,進行讀取。csv常見編碼格式:UTF-8、GBK 、ISO-8859-1
根據(jù)上面的代碼結(jié)果,我們可以初步了解的數(shù)據(jù)的基本情況如下:import pandas as pd data= pd.read_csv(r'superstore_dataset2011-2015.csv',encoding='ISO-8859-1')print('每個字段中是否含有空值:/n', data.isna().any())
發(fā)現(xiàn)Postal Code字段含有缺失值。而該字段并不在我們的分析范圍內(nèi),我們可以不處理該字段的缺失值,同時也保留了該字段所在數(shù)據(jù)其他字段的數(shù)據(jù),這樣可以確保分析的準確度。data.describe()
出結(jié)果指標包括count,mean,std,min,max以及第25百分位,中位數(shù)(第50百分位)和第75百分位。通過觀察該結(jié)果,發(fā)現(xiàn)數(shù)據(jù)集并無異常值存在。data['Order Date'] = pd.to_datetime(data['Order Date'])print(data.dtypes)
上面我們將Order Date(訂單日期)列的數(shù)據(jù)類型成功修改成了datetime類型,因為在通過datetime可以快速的增加數(shù)據(jù)的維度,例如:年、月、季度等。# 通過dt屬性返回的對象中可以獲取datetime中的年與日等數(shù)據(jù)data['Order-year'] = data ['Order Date'].dt.yeardata ['Order-month'] = data ['Order Date'].dt.monthdata ['quarter'] = data ['Order Date'].dt.to_period('Q')result = data [['Order Date','Order-year','Order-month', 'quarter']].head()display(data.head())
七:具體分析目標sales_year = data.groupby(by='Order-year')['Sales'].sum()print(sales_year)
b,根據(jù)銷售額增長率公式分別算出2012年、2013年和2014年的銷售額增長率sales_rate_12 = sales_year[2012] / sales_year[2011] -1sales_rate_13 = sales_year[2013] / sales_year[2012] -1sales_rate_14 = sales_year[2014] / sales_year[2013] -1print(sales_rate_12,sales_rate_13,sales_rate_14)
用百分數(shù)的形式結(jié)果sales_rate_12 = "%.2f%%" % (sales_rate_12 * 100)sales_rate_13 = "%.2f%%" % (sales_rate_13 * 100)sales_rate_14 = "%.2f%%" % (sales_rate_14 * 100)print(sales_rate_12,sales_rate_13,sales_rate_14)
import matplotlib.pyplot as pltimport matplotlib as mpl# #由于百分比數(shù)據(jù)不支持繪圖,所以重新求占比sales_rate_12 = sales_year[2012] / sales_year[2011] - 1sales_rate_13 = sales_year[2013] / sales_year[2012] - 1sales_rate_14 = sales_year[2014] / sales_year[2013] - 1print(sales_rate_12,sales_rate_13,sales_rate_14)# 設(shè)置字體#修改matplotlib 配置文件mpl.rcParams['font.sans-serif'] = ['SimHei']# 設(shè)置風(fēng)格plt.style.use('ggplot')sales_rate = pd.DataFrame({'sales_all':sales_year, 'sales_rate':[0,sales_rate_12,sales_rate_13,sales_rate_14]})y1 = sales_rate['sales_all']y2 = sales_rate['sales_rate']x = [str(value) for value in sales_rate.index.tolist()]# 新建figure對象fig=plt.figure() # 新建子圖1ax1=fig.add_subplot(1,1,1)# ax2與ax1共享X軸ax2 = ax1.twinx()ax1.bar(x,y1,color = 'blue')ax2.plot(x,y2,marker='*',color = 'r')ax1.set_xlabel('年份')ax1.set_ylabel('銷售額')ax2.set_ylabel('增長率')ax1.set_title('銷售額與增長率')plt.show()
結(jié)合上面的圖表可以發(fā)現(xiàn),2011年-2014年該超市的銷售額在穩(wěn)步上升,說明企業(yè)市場占有能力在不斷提高,增長率2012年-2014年在增長后趨于平穩(wěn),說明企業(yè)經(jīng)營在逐步穩(wěn)定。同樣我們根據(jù)銷售和增長率,可以初步制定下一年度的銷售額指標是:530萬左右,當然具體銷售額指標的制定還要再結(jié)合公司的整體戰(zhàn)略規(guī)劃。sales_area = data.groupby(by='Market')['Sales'].sum()sales_area.plot(kind='pie',autopct="%1.1f%%",title='2011年-2014年的總銷售額占比')
從占比圖中可以看出APAC地區(qū)銷售額占比最大為28.4%,而Canada地區(qū)的銷售額占比最少,并且只有0.5%,說明市場幾乎沒有打開,可以根據(jù)公司的總體戰(zhàn)略部署進行取舍,從而根據(jù)銷售額占比分配下一年的銷售額指標sales_area = data.groupby(by=['Market','Order-year'])['Sales'].sum()sales_area# # # 將分組后的多層索引設(shè)置成列數(shù)據(jù)sales_area = sales_area.reset_index(level=[0,1])sales_area# # # 使用數(shù)據(jù)透視表重新整理數(shù)據(jù)sales_area = pd.pivot_table(sales_area, index='Market', columns='Order-year', values='Sales')sales_area# # # 繪制圖形sales_area.plot(kind = 'bar',title = '2011年-2014年不同地區(qū)銷售額對比')
從上面的圖形中可以看出,各個地區(qū)的2011年-2014年銷售總額均是增長的趨勢,在APAC地區(qū)和EU地區(qū)的增長速度比較快速,可以看出市場占有能力也在不短增加,企業(yè)市場前景比較好,下一年可以適當加大運營成本,其他地區(qū)可以根據(jù)自身地區(qū)消費特點,吸取上面兩個地區(qū)的運營模式category_sales_area = data.groupby(by=['Market','Category'])['Sales'].sum()category_sales_area# 將分組后的多層索引設(shè)置成列數(shù)據(jù)category_sales_area = category_sales_area.reset_index(level=[0,1])# 使用數(shù)據(jù)透視表重新整理數(shù)據(jù)category_sales_area = pd.pivot_table(category_sales_area, index='Market', columns='Category', values='Sales')# 繪制圖形category_sales_area.plot(kind = 'bar', title = '不同類型產(chǎn)品在不同地區(qū)銷售額對比', figsize= (10,8) )
所有產(chǎn)品按照三個大的類型進行了區(qū)分,分別是Furniture(家具)、Technology(電子產(chǎn)品)、Office Supplies(辦公用品)。通過上圖我們大致可以看出,在各大地區(qū)銷售額都比較高是電子產(chǎn)品,可以根據(jù)企業(yè)的整體戰(zhàn)略部署適當?shù)募哟髮Ω鞯貐^(qū)該品類的投入,以便擴大優(yōu)勢。year_month = data.groupby(by=['Order-year','Order-month'])['Sales'].sum()# 將索引訂單年轉(zhuǎn)為一列數(shù)據(jù)sales_year_month = year_month.reset_index(level=[0,1])# 利用透視表的確定銷售額預(yù)覽表sales_year_month = pd.pivot_table(sales_year_month, index='Order-month', columns='Order-year', values='Sales')# 繪制圖形sales_year_month.plot()
通過圖表我們基本可以看出,該超市2011年-2014年每一年的銷售額同比上一年都是上升趨勢,所以很容易發(fā)現(xiàn)該超市的旺季是下半年,另外,我們在上半年銷售額中發(fā)現(xiàn)6月份的銷售額也是比較高的,所以可以在6月份開始加大一些運營成本,進而更大一步提高銷售額,但是需要注意是下半年的7月份和10月份銷售額會有明顯的下降,可以針對這些下降的月份多舉行一些營銷活動。dt = data.drop_duplicates(subset=['Customer ID'])new_consumer = dt.groupby(by=['Order-year','Order-month']).size()new_consumer = new_consumer.reset_index(level=[0,1])sales_year_month = pd.pivot_table(new_consumer, index='Order-month', columns='Order-year', values=0)print(sales_year_month)
根據(jù)圖表可以看出,從2011年開始到2014年總體看,每一年的新增客戶數(shù)是逐年減少的趨勢,可以看出該網(wǎng)站對保持老用戶是有效的,網(wǎng)站的運營狀況較為穩(wěn)定。但是,新客戶獲取率比較低,可以不定期的進行主動推廣營銷,從而增加新客戶數(shù)# 獲取2014年數(shù)據(jù)data_14 = data [data ['Order-year']==2014]# 獲取三列數(shù)據(jù)#rfm 用這三列數(shù)據(jù)就可以制定rfmdata_14 = data_14[['Customer ID','Order Date','Sales']]data_14.head()
由于RFM模型分別對應(yīng)著Customer ID、Order Date、Sales這三個字段,所以我們只獲取這三個字段的數(shù)據(jù)。# 排序函數(shù)def order_sort(group):# print(group.sort_values(by='Order Date'))[-1:] return group.sort_values(by='Order Date')[-1:]# 將數(shù)據(jù)按客戶ID分組data_14_group = data_14.groupby(by='Customer ID',as_index = False)# 將每個分組對象的數(shù)據(jù)排序,并取出日期最大的數(shù)據(jù)data_max_time = data_14_group.apply(order_sort)print(data_max_time.head())
第三步,經(jīng)過分組之后同樣可以快速算出RFM模型中的F(購買次數(shù))和M(銷售額總數(shù))。# 為數(shù)據(jù)添加F列data_max_time['F'] = data_14_group.size().values# print(data_14_group.size())data_max_time['F'] # 為數(shù)據(jù)添加M列data_max_time['M'] = data_14_group.sum()['Sales'].valuesdata_max_time.head()
第四步,目前已經(jīng)獲取到了2014年每個客戶最后一次的時間了,現(xiàn)在需要根據(jù)假定同時間計算出最近一次交易時間的間隔。# 確定統(tǒng)計日期stat_date = pd.to_datetime('2014-12-31')# 計算最近一次交易時間的間隔r_data = stat_date - data_max_time['Order Date']# 為數(shù)據(jù)添加R列data_max_time['R'] = r_data.valuesprint(data_max_time.head())
第五步,經(jīng)過上面四步分別計算出來RFM各個維度的數(shù)值,現(xiàn)在可以根據(jù)經(jīng)驗以及業(yè)務(wù)場景設(shè)定分值的給予區(qū)間,本項目中給定F的區(qū)間為[0,5,10,15,20,50],然后采用5分制的評分規(guī)則與上面分值區(qū)間一一對應(yīng),例如:1-5對應(yīng)的為1、5-10對應(yīng)的為2,依次類推。section_list_F = [0,5,10,15,20,50]# 根據(jù)區(qū)間設(shè)置評分grade_F = pd.cut(data_max_time['F'],bins=section_list_F,labels=[1,2,3,4,5])# 添加FS評分列data_max_time['F_S'] = grade_F.valuesdata_max_time.head()
第六步,根據(jù)第五步的思路,首先確定M維度的區(qū)間[0,500,1000,5000,10000,30000],然后采用5分制的評分規(guī)則與上面分值區(qū)間一一對應(yīng)。同理,確定R維度的區(qū)間為[-1,32,93,186,277,365],但是R維度所對應(yīng)的評分順序應(yīng)該與F和M的相反。# 設(shè)置M維度的評分section_list_M = [0,500,1000,5000,10000,30000]# 根據(jù)區(qū)間設(shè)置評分grade_M = pd.cut(data_max_time['M'],bins=section_list_M,labels=[1,2,3,4,5])# 添加FS評分列data_max_time['M_S'] = grade_M.valuesdata_max_time# 設(shè)置R維度的評分import datetimesection_list_R = [datetime.timedelta(days=i) for i in [-1,32,93,186,277,365]]# 根據(jù)區(qū)間設(shè)置評分grade_R = pd.cut(data_max_time['R'],bins=section_list_R,labels=[5,4,3,2,1])# 添加FS評分列data_max_time['R_S'] = grade_R.valuesdata_max_time.head()
第七步,上面給每條數(shù)據(jù)的RFM都設(shè)置了對應(yīng)的評分,現(xiàn)在需要根據(jù)每一個維度,計算出對應(yīng)的平均分,然后用對應(yīng)的分數(shù)與平均值進行對比,大于平均分的值的標記成1,同理小于平均分的值的標記成0# 設(shè)置F維度高低值data_max_time['F_S'] = data_max_time['F_S'].values.astype('int')# 根據(jù)評分平均分設(shè)置判別高低grade_avg = data_max_time['F_S'].values.sum()/data_max_time['F_S'].count()grade_avg# # 將高對應(yīng)為1,低設(shè)置為0data_F_S = data_max_time['F_S'].where(data_max_time['F_S']>grade_avg,0)data_max_time['F_high-low']=data_F_S.where(data_max_time['F_S']<grade_avg,1).valuesdata_max_time['F_high-low']# # 設(shè)置M維度高低值data_max_time['M_S'] = data_max_time['M_S'].values.astype('int')# # 根據(jù)評分平均分設(shè)置判別高低grade_avg = data_max_time['M_S'].values.sum()/data_max_time['M_S'].count()# # 將高對應(yīng)為1,低設(shè)置為0data_M_S = data_max_time['M_S'].where(data_max_time['M_S']>grade_avg,0)data_max_time['M_high-low']=data_M_S.where(data_max_time['M_S']<grade_avg,1).values# # 設(shè)置R維度高低值data_max_time['R_S'] = data_max_time['R_S'].values.astype('int')# 根據(jù)評分平均分設(shè)置判別高低grade_avg = data_max_time['R_S'].values.sum()/data_max_time['R_S'].count()# 將高對應(yīng)為1,低設(shè)置為0data_R_S = data_max_time['R_S'].where(data_max_time['R_S']<grade_avg,0)data_max_time['R_high-low']=data_R_S.where(data_max_time['R_S']>grade_avg,1).valuesdata_max_time.head()
第八步,現(xiàn)在基本完成對每個數(shù)據(jù)的RFM高低值的設(shè)置,記下來就可以根據(jù)RFM的高低值對每個用進行類型標記了# 截取部分列數(shù)據(jù)data_rfm = data_max_time.loc[:,['Customer ID','R_high-low','F_high-low','M_high-low']]def get_sum_value(series):# print([str(i) for i in series.values.tolist()]) return ''.join([str(i) for i in series.values.tolist()[1:]])# 添加RFM字符串列data_rfm['data_rfm'] = data_rfm.apply(get_sum_value, axis=1)data_rfm['data_rfm']dic = { '111':'重要價值客戶', '101':'重要發(fā)展客戶', '011':'重要保持客戶', '001':'重要挽留客戶', '110':'一般價值客戶', '100':'一般發(fā)展客戶', '010':'一般保持客戶', '000':'一般挽留客戶',}# # RFM字符串數(shù)據(jù)映射成對應(yīng)類型文字data_rfm['data_rfm'] = data_rfm['data_rfm'].map(dic)print(data_rfm.head())print(data_rfm.tail())
經(jīng)過以上步驟,已經(jīng)給所有的用戶都設(shè)置好RFM的標簽,現(xiàn)在讓我們來看一下2014年不同類型人群占比。size = data_rfm.groupby(by='data_rfm').size()size = size.to_frame()size['rfm_pct'] = ["%.2f%%" % (i/sum(size.values) * 100) for i in size.values]print(size)
結(jié)論依據(jù):關(guān)鍵詞:分析,數(shù)據(jù),銷售
微信公眾號
版權(quán)所有? 億企邦 1997-2025 保留一切法律許可權(quán)利。