1. 程式人生 > >用實戰玩轉pandas資料分析(一)——使用者消費行為分析(python)

用實戰玩轉pandas資料分析(一)——使用者消費行為分析(python)

  CD商品訂單資料的分析總結。根據訂單資料(使用者的消費記錄),從時間維度和使用者維度,分析該網站使用者的消費行為。通過此案例,總結訂單資料的一些共性,能通過使用者的消費記錄挖掘出對業務有用的資訊。對其他產品的線上消費資料分析有一定的借鑑價值,能達到舉一反三的效果。 訂單交易資料分析 [toc] ------------ # 一、案例背景   CDNOW是一家美國線上零售商,主營商品為CD唱片,ToC業務。1998年上市,2000年被貝塔斯曼收購。網上有一份使用者訂單消費資料集:CDNOW訂單資料集 ------------ # 二、案例目的   這份資料集只包含了四個基本資訊欄位:***使用者ID、購買日期、購買數量、購買金額***。本案例的目標:通過這個四個欄位,在資料集時間視窗內,分析使用者消費的基本概況;通過使用者分層、週期分析、復購率和回購率分析等,梳理現階段使用者的價值現狀,並嘗試根據業務經驗提一些運營建議。 ------------ # 三、分析框架 ![image](https://img2020.cnblogs.com/blog/2104707/202103/2104707-20210312174431631-983489915.png) ![image](https://img2020.cnblogs.com/blog/2104707/202103/2104707-20210312174504115-2057656715.png) ------------ # 四、分析過程 ## 4.1資料載入和初探 **(1)匯入相關包、設定風格樣式** ```python import pandas as pd import numpy as np import matplotlib.pyplot as plt import os # jupter魔法函式,設定視覺化頁內顯示 %matplotlib inline # 正常顯示中文和負號 plt.rcParams['font.sans-serif'] = ['SimHei'] plt.rcParams['axes.unicode_minus'] = False # 畫圖的樣式風格設定為:ggplot plt.style.use('ggplot') ``` **(2)匯入資料集** 欄位資訊: * user_id:使用者ID * order_dt:購買日期 * order_products:購買數量 * order_amount:購買金額 源資料為txt檔案,通過pd.read_csv()。分割符為空白字串,用正則表達'\s+',匹配任意空白符。 ```python # 匯入資料集 os.chdir(r'D:/資料集/電商零售類/CDNOW資料集/') columns = ['user_id', 'order_dt', 'order_products', 'order_amount'] df = pd.read_csv('CDNOW_Dataset.txt',delimiter='\s+',names=columns) df.head() ```   從前5行資料中可以發現:同一個使用者在同一天可能購買多次、同一使用者在不同時間購買多次等消費現象。 **(3)資料清洗** ```python df.info() ```   源資料質量描述:資料不存在缺失值,但購買日期order_dt欄位資料型別為int64,需要轉換為日期型datetime64[ns] ```python # 'order_dt'欄位型別轉換 df['order_dt'] = pd.to_datetime(df['order_dt'],format='%Y%m%d') ```   按月份分析銷售趨勢,新增month欄位。(tip:datetime64[M]:每月的第一天日期,datetime64[Y]:每年的第一天日期。) ```python # 新增month欄位 df['month'] = df['order_dt'].values.astype('datetime64[M]') ``` ```python # 檢視欄位的資料型別 df.dtypes ```
```python df.head() ``` **(4)資料初探** ```python # 資料描述性統計分析 df.describe() ``` 描述性統計分析: * 使用者平均每筆訂單購買2.4件商品,中位數為2.0,資料呈現正偏態(右偏)特徵,最大值99,需要關注極值點(為何該使用者同時買了那麼多CD); * 使用者平均訂單金額為35.89,中位數為25.98,資料同樣呈現正偏態(右偏)特徵,大部分訂單金額都集中在中小額範圍(14.4~43.7),存在極值點。 ------------ ## 4.2消費概況分析 ### 4.2.1時間維度分析消費情況(按月)   按月份降取樣,統計資訊。 ```python df_dtindex = df.set_index(['order_dt']) # 統計每月訂單商品量、每月訂單金額 month_grouped = df_dtindex.resample('m').sum()[['order_products','order_amount']] # 統計每月消費人數 month_grouped['user_num'] = df_dtindex.resample('m')['user_id'].nunique() # 統計每月訂單數 month_grouped['order_quantity'] = df_dtindex.resample('m')['user_id'].size() month_grouped.head() ```
  每月訂單商品量、每月訂單金額、每月消費人數、每月訂單數趨勢圖。 ```python month_grouped.plot(kind='line',subplots=True,figsize=(10,8)) ``` 從折線趨勢圖可以看出: * 1-3月份訂單商品量和訂單金額都較高,4月份急速下降後趨於平緩; * 1-3月份月均消費人數在7800~9600之間,4月份開始月均消費人數開始下降,在2000人次附近波動,反應使用者粘性不高,留存率低。 出現以上的原因,可能是該網站1-3月份做大推廣;或者明星新CD專輯集中釋出,大量粉絲湧入網站購買。 ------------ ###4.2.2使用者維度分析消費情況 ####4.2.2.1個體消費分析 **(1)使用者消費次數、消費金額、訂單商品量描述性統計** ```python # 對使用者分組,並統計每個使用者的消費次數、消費金額、訂單商品量 user_grouped = df.groupby('user_id').agg({'user_id': 'count','order_amount': 'sum','order_products': 'sum'}) # 列欄位重新命名consumptions:消費次數 user_grouped.rename(columns={'user_id':'consumptions'},inplace=True) # 描述性統計 user_grouped.describe() ```
使用者維度消費情況描述性統計分析: * 使用者平均消費次數為2.96次,中位數1,使用者消費次數資料右偏,反映時間段內大部分使用者只在該網站消費1次。 * 訂單金額和訂單商品量的均值與75%分位值接近,反映訂單金額和訂單商品量主要由少部分使用者貢獻,要關注極值點影響。 **(2)使用者消費次數、消費金額、訂單商品量分佈直方圖** ```python plt.figure(figsize=(20,4)) plt.subplot(1,3,1) user_grouped['consumptions'].plot.hist(bins=15,title='consumptions') plt.subplot(1,3,2) user_grouped['order_amount'].plot.hist(bins=30,title='order_amount') plt.subplot(1,3,3) user_grouped['order_products'].plot.hist(bins=30,title='order_products') ```   資料分佈存在一定的極值干擾,需要對極值進行過濾處理再觀察資料分佈特徵。對於非正態分佈資料集,根據切比雪夫定理:所有資料,至少有24/25(或96%)的資料位於均值±5個標準差範圍內。根據描述性統計,分別計算過濾條件: * consumptions:mean + 5std = 2.95+5*4.73=26.6,選擇27作為過濾閾值 * order_amount:160.08+5*240.93=1310.73,選擇1310作為過濾閾值 * order_products:7.12+5*16.98=92.02,選擇95作為過濾閾值 ```python # 過濾極值,畫分佈直方圖 plt.figure(figsize=(20,4)) plt.subplot(1,3,1) user_grouped.query('consumptions<27')['consumptions'].plot.hist(bins=15,title='consumptions',xlim=(0,27)) plt.subplot(1,3,2) user_grouped.query('order_amount<1312')['order_amount'].plot.hist(bins=30,title='order_amount') plt.subplot(1,3,3) user_grouped.query('order_products<95')['order_products'].plot.hist(bins=30,title='order_products') ``` ![image](https://img2020.cnblogs.com/blog/2104707/202103/2104707-20210311170141196-603200049.png)   過濾掉極值之後,從使用者消費次數、消費金額、訂單商品量分佈直方圖可以明顯看出:資料大多數集中在低值區,反映大部分使用者消費水平一般,貢獻價值一般。符合“長尾型”消費類資料分佈特徵。 **(3)使用者人數累計消費金額佔比** ```python user_cumsum = user_grouped.sort_values(['order_amount']).apply(lambda x:x.cumsum()/x.sum()) user_cumsum.reset_index()['order_amount'].plot(xticks=(range(0,25000,2500)),title='使用者人數累計消費金額佔比') plt.xlabel('人數') plt.ylabel('佔比') ``` 由上圖可知:   50%的使用者(總共有23570名使用者)僅貢獻了15%的消費額度,70%的使用者僅貢獻了20%的消費額度,85%的使用者僅貢獻了40%的消費額度,而前3570(佔比15%)多使用者就貢獻了60%的消費額度。可以重點關注一下這15%客戶更多相關資料,總結使用者特徵,挖掘更多消費機會。 **(4)使用者消費金額和訂單商品量之間相關性分析** ```python user_grouped.query('order_amount<8000').plot.scatter(x='order_products',y='order_amount',title='使用者消費金額和商品購買量散點分佈') ``` 由散點分佈圖可以看出:   使用者的消費金額和訂單商品量幾乎成線性關係:購買的商品越多,消費金額越大。反映該網站的商品比較單一,或者單價比較穩定。在不影響主商品的前提下,可以考慮一些輔助商品鋪設。 ####4.2.2.2 使用者消費行為分析 **(1)使用者第一次消費(首購)和最後一次消費時間分佈(按月)** ```python # 使用者初次消費時間分佈:統計每個使用者消費的時間最小值,再計算相同日期的頻數 df.groupby('user_id')['order_dt'].min().value_counts().plot(title='使用者初次消費時間分佈圖') ``` 由初次消費分佈圖可知:   使用者初次購買時間集中在前三個月,其中2月9日到2月25日之間有波動。可能是該網站做了推廣或者明星集中發專輯,導致大量新使用者湧入網站購買CD。 ```python # 使用者最後一次消費時間分佈 df.groupby('user_id')['order_dt'].max().value_counts().plot(title='使用者最後一次消費時間分佈圖') ``` 由末次消費分佈圖上圖可知: * 使用者最後一次消費也集中在前三個月,反映有大量使用者在三個月內就流失掉了; * 首購和最後一次消費都集中前三個月,可能是這部分新增使用者在前三月就流失掉了。可能是著名明星集中發專輯,新增使用者對其他CD專輯不感興趣。(這部分新使用者是某類明星的粉絲) * 隨時間遞增,最後一次消費人數也在緩慢遞增,使用者流失呈上升趨勢。可能是運營沒跟上,老使用者忠誠度也下降了。 從這裡簡要看出,要提高網站的銷售金額,有兩個關鍵點: * 第一,分析新增使用者的購物喜好,推送同類或類似風格產品,確保在使用者流失之前留住使用者; * 第二,分配合理資源維護老使用者,給老使用者做合理的引導消費通知。 **(2)新老使用者佔比分析**   **僅消費一次的使用者佔比** ```python # 僅消費一次的使用者佔比=消費一次的使用者人數/總使用者數 user_grouped[user_grouped['consumptions']==1]['consumptions'].count()/user_grouped['consumptions'].count() ``` 結果表明:有一半使用者只消費了一次。 **注意:**這裡不能用第一次和最後一次消費日期相同,來判斷該使用者只消費了一次,因為有可能同一天該使用者消費了兩次。這樣算出來的指標應該叫‘僅消費一天的使用者佔比’,不過兩者結果相差應該不是很大。   **每月新使用者佔比** ------------ ##4.3使用者分層分析 ###4.3.1FRM模型對使用者分層 R(Recency,近度/最近一次消費)F(Frequency,消費頻次)M(Monetary,消費金額) ```python # 首先,資料透視表求出使用者的最近一次消費時間、消費次數,消費總金額 rfm = df.pivot_table(index='user_id', values=['order_dt','order_products','order_amount'], aggfunc={'order_dt': 'max', 'order_products': 'count', 'order_amount': 'sum'}) rfm.head() ``` ```python # 其次,計算R值:最近一次消費(距今天數),資料比較久遠,這裡選擇order_dt的最大值為‘今天’ # 時間格式相減,得到xxx days,需要除以一個單位'D' rfm['R'] = (rfm.order_dt-rfm.order_dt.max())/np.timedelta64(1,'D') rfm = rfm.rename(columns={'order_amount': 'M', 'order_products': 'F'})[['R','F','M']] rfm.head() ``` ```python # 根據判斷閾值(這裡選擇每列均值作為閾值),新增客戶分層標籤欄位 # 定義使用者分層函式 def rfm_level(data): # 和閾值(均值)做對比:高於閾值賦值為1,低於閾值賦值為0 level = data.apply(lambda x:'1' if x>=0 else '0') # 構建分類字典 d = { '111': '重要價值客戶', '011': '重要保持客戶', '101': '重要發展客戶', '001': '重要挽留客戶', '110': '一般價值客戶', '010': '一般保持使用者', '100': '一般發展客戶', '000': '一般挽留客戶' } # 拼接字串 label = level.R + level.F + level.M # 各行根據拼接字串的結果(鍵),返回客戶型別(值) return d[label] # 逐行傳入 rfm['label'] = (rfm-rfm.mean()).apply(rfm_level,axis=1) rfm.head() ``` ```python plt.figure(figsize=(12,6),dpi=80) plt.subplot(1,2,1) rfm.label.value_counts().plot.pie(autopct='%3.1f%%',title='RFM模型分層使用者人數佔比圖') plt.subplot(1,2,2) rfm.groupby('label').M.sum().plot.pie(autopct='%3.1f%%',title='RFM模型分層使用者消費金額佔比圖') ``` 由上圖可知: * ‘一般挽留客戶’人數佔比最多,達到57.7%。但貢獻的消費金額僅佔比16.4% * ‘重要價值客戶’人數佔比為19.6%,貢獻消費佔比卻達到了63.7% 此次分析中,R、F、M三個維度的閾值是依據各自的平均值選定,實際業務要根據不同場景設定合適的閾值,切莫不要為了資料好看劃分等級。在資源的有限情況下,儘量用小部分的使用者覆蓋大部分的額度。在運營策略上,應結合使用者分層的結果,針對不同的使用者分類使用者制定不同的運營策略: * 針對重要價值客戶,應保持好現狀; * 針對重要發展客戶,由於其價值高但是頻次低,應採取合適的策略來刺激其消費頻率; * 針對重要保持使用者,應採取合適的策略來將其召回,留住該使用者; * 針對重要挽留使用者,召回他並刺激其消費; * 針對一般價值使用者,可以通過發放大額面值優惠券等方式刺激消費力度; * 其餘幾類使用者都要在考慮成本、資源的情況下采取相應的策略召回、刺激消費。 ------------ ###4.3.2根據消費狀態對使用者分層   使用者分層的目的在於區分不同價值的使用者,對不同價值的使用者、不同階段的使用者採用精準、細化的運營方案。在實際業務場景中,常常把使用者分為新客,不活躍使用者,活躍使用者,迴流使用者。 **指標口徑說明:** * 新使用者:時間視窗內,首次消費的使用者。 * 不活躍使用者(流失使用者):時間視窗內,未消費的老客。 * 活躍使用者:本時間視窗內有消費,上一個時間視窗也有消費的使用者。 * 迴流使用者:上一個時間視窗中沒有消費,而在當前時間視窗內有過消費的老客。 ```python # 首先,以月份為統計視窗,製作透視表:得到每個月使用者的消費次數 # 缺失值NaN(該月份無消費記錄)用0填充 pivoted_counts = df.pivot_table(index='user_id', columns='month', values='order_dt', aggfunc='count').fillna(0) pivoted_counts.head() ``` ![image](https://img2020.cnblogs.com/blog/2104707/202103/2104707-20210312145007299-1714164583.png)   上面的NaN值用0填充:0不一定代表本月沒有消費,也有可能該使用者在當月沒有註冊,為了判斷該使用者在當月是否為新使用者,還需用自定義函式來判斷。 ```python # 然後,自定義使用者分層函式 def user_status(data): ''' unreg:未註冊使用者 new:新使用者 unactive:不活躍使用者(流失使用者) active:活躍使用者 return:迴流使用者 ''' status = [] # 判斷第一月是否為新使用者 if data[0] == 0: status.append('unreg') else: status.append('new') # 迴圈判斷每一個月的使用者狀態 for i in range(17): # 若本月未消費 if data[i+1]==0: # 上一個月也未消費,則本月為未註冊使用者 if status[i] == 'unreg': status.append('unreg') else: status.append('unactive') # 本月消費 else: # 上一月為未註冊使用者,則本月為新使用者 if status[i] == 'unreg': status.append('new') # 上一月為不活躍使用者,則本月為迴流使用者 elif status[i] == 'unactive': status.append('return') # 上一月消費,本月也消費,則本月為活躍使用者 else: status.append('active') return pd.Series(status,index=data.index) pivoted_user_status = pivoted_counts.apply(user_status, axis=1) pivoted_user_status.head() ``` ![image](https://img2020.cnblogs.com/blog/2104707/202103/2104707-20210312145223530-1728484557.png) ```python # 統計每個月不同狀態的使用者數 # 把未註冊unreg替換為NaN值,count不會計數 user_status_counts = pivoted_user_status.replace('unreg',np.NaN).apply(pd.value_counts) user_status_counts ``` ![image](https://img2020.cnblogs.com/blog/2104707/202103/2104707-20210312145500336-2045254729.png) ```python # 繪製不同型別使用者數量隨時間變化的曲線 user_status_counts.T.plot(figsize=(10, 4),title='不同型別使用者數量隨時間變化的曲線圖',grid=False) ``` 由上圖可知: * 前三個月新使用者大量湧入,後期沒有新增; * 後期不活躍使用者數量非常多,基本每個月20000人以上; * 活躍使用者前幾月較多,後期逐漸下降; * 迴流使用者基本保持1000左右。 在實際業務中,活躍使用者和迴流使用者是真正意義上消費的使用者,是運營應該重點關注的高價值群體。 ```python #計算每個月各類使用者佔比 user_status_counts.T.apply(lambda x: x/x.sum(), axis=1).round(2) ``` ------------ ##4.4使用者生命週期分析 **(1)使用者生命週期分佈直方圖**   使用者生命週期定義:第一次消費至最後一次消費的時間差。   延長使用者的生命週期,在使用者生命週期內獲取更多價值,是使用者運營的目標。 ```python # LTV:生命週期總價值,即生命週期內消費的總金額 user_LTV = df.groupby(['user_id']).agg({'order_amount': 'sum'}) user_LTV['lifetime'] = (df.groupby(['user_id'])['order_dt'].max()-df.groupby(['user_id'])['order_dt'].min())/np.timedelta64(1, 'D') user_LTV.head() ```   前面分析中,有一半以上的使用者只消費1次,再進行使用者生命週期分析時,需要過濾掉這部分使用者再分析才具有實際意義。因為只消費1次的使用者生命週期為0,會把整體資料拉低,而且大部分一次性使用者創造的價值很小,對後期使用者運營沒有顯著的幫助。 ```python # 使用者生命週期描述性統計:排除只消費1次的使用者 user_LTV_query = user_LTV[user_LTV['lifetime'] > 0] user_LTV_query.describe() ``` ```python #繪製分佈直方圖 user_LTV_query['lifetime'].plot.hist(bins=40,figsize=(10, 6),title='CDNOW使用者生命週期分佈直方圖') ``` 由描述性統計和分佈直方圖可以看出: * 消費2次以上使用者平均生命週期為276天; * 分佈直方圖呈現雙峰趨勢,大體可以分為三段: 1. [0-30]天,有部分使用者雖然消費超過兩次,但是無法持續,運營應該在30天內做出對策,延長使用者生命週期; 2. [50-350]天,屬於普通型生命週期,這部分使用者是有消費慾望的,可以根據其特點推出針對性營銷策略; 3. [>350]天,屬於網站的忠誠使用者,要用心維護,穩定銷量。 **(2)使用者生命週期和使用者生命週期總價值相關性** ```python plt.scatter(x=user_LTV_query['lifetime'],y=user_LTV_query['order_amount']) ``` ```python user_LTV_query = user_LTV_query.query('order_amount < 4000') plt.scatter(x=user_LTV_query['lifetime'],y=user_LTV_query['order_amount']) plt.title('使用者生命週期和使用者生命週期總價值散點圖') ``` 由上散點分佈圖可知:   使用者生命週期和使用者生命週期總價值無線性相關關係,但是有一部分生命週期超過350天的使用者,貢獻的消費金額明顯高於生命週期偏低的使用者。 ------------ ##4.5使用者留存分析   使用者在某段時間內開始使用應用,經過一段時間後,仍然繼續使用該應用的使用者,被認作是留存使用者。這部分使用者佔當時新增使用者的比例即是留存率,會按照每隔1單位時間(例日、周、月)來進行統計。留存使用者和留存率體現了使用者的質量和運營保留使用者的能力。 ```python # 獲取使用者留存資料表 # 獲取使用者的啟用日期reg_dt:這裡指第一次消費日期 reg_dt = df.groupby('user_id')['order_dt'].min().reset_index().rename(columns={'order_dt': 'reg_dt'}) # 內連線 user_retention = pd.merge(left=df,right=reg_dt,how='inner',on='user_id')[['user_id','order_amount','reg_dt','order_dt']] user_retention['第n天活躍'] = (user_retention['order_dt'] - user_retention['reg_dt']).apply(lambda x: x.days) # # 對活躍天數進行分箱 bins = [0, 3, 7, 15, 30, 60, 90, 180, 365] user_retention['活躍天數區間'] = pd.cut(user_retention['第n天活躍'], bins=bins) user_retention.head(10) ``` ```python # 資料透視,獲取使用者維度留存表 user_retention_pivoted = user_retention.pivot_table(index='user_id', columns='活躍天數區間',values='order_amount',aggfunc=sum,dropna=False) user_retention_pivoted.head(10) ``` ```python # 統計各個時間段使用者的消費比列:即首次消費後,有多少使用者比例在各個時間段再次消費 retention = user_retention_pivoted.count()/len(user_retention_pivoted) retention ``` ```python retention.plot.bar(title = '各個時間段使用者的再次消費人數佔比') ``` 由上柱狀圖可知: * 約有2.7%的使用者在第一次消費後,次日至3日內再次消費; * 3.6%的使用者在3至7日消費; * 約20%的使用者在第一次消費三個月至半年內有過消費記錄; * 約26%的使用者在半年後至一年內購買過。 可見,CD商品購買不屬於高頻行為。從運營角度看,在促活新使用者的時,更要注重培養老使用者的忠誠度。 ```python # 統計使用者在第一次消費後,再後續時間段的平均消費 user_retention_pivoted.mean() ``` ------------ ##4.5使用者購買週期分析 ```python # 計算使用者的相鄰兩個訂單的時間間隔,shift函式是對資料進行錯位,所有資料會往下平移一下 order_dt_diff = user_retention.groupby('user_id').apply(lambda x: x.第n天活躍 - x.第n天活躍.shift(1)) order_dt_diff.head(10) ``` ```python # 使用者消費時間間隔描述性統計 order_dt_diff.describe() ```   使用者平均消費時間間隔為69天(極值影響)。在運營策略中,可以大概理解為,想要召回使用者消費,在60天左右的時間間隔可以做一些好的運營策略或推薦。 ```python # 使用者消費時間間隔分佈直方圖 order_dt_diff.plot.hist(bins=50,title='使用者消費時間間隔分佈直方圖') ``` 由使用者消費時間間隔分佈直方圖,可以看出:   直方圖呈現長尾分佈,大部分使用者的消費時間間隔很短,在使用者第一次消費後,將時間召回點設為消費後立即贈送優惠券,消費後15天詢問使用者CD怎麼樣,消費後20天提醒優惠券到期,消費後60天簡訊推送,以實現使用者粘性增加,並不斷刺激使用者消費。 ------------ ##4.6復購率和回購率分析 指標說明:(這裡時間視窗為月) * 復購率:在單位時間視窗內多次(2次及以上)消費的使用者在總消費使用者的佔比。 * 回購率:在某單位時間視窗內消費的使用者,在下一單位時間視窗仍消費的佔比。 ```python # 計算每個月使用者的消費次數 pivoted_counts.head() ``` ![image](https://img2020.cnblogs.com/blog/2104707/202103/2104707-20210312153246793-692219127.png) **(1)復購率分析** ```python # 消費次數:>1表示消費兩次以上,>=1表示有消費 month_buy_rate = pd.DataFrame((pivoted_counts>1).sum()/(pivoted_counts>=1).sum(),columns=['復購率']) month_buy_rate.head() ``` ```python month_buy_rate.plot(figsize=(10,4),title='復購率月趨勢圖') ``` 由復購率月趨勢圖可知: * 前三個月,由於新使用者湧入,導致復購率偏低,新客在短時間內只購買了一次 * 隨著時間的推移,留下的都是少量忠誠使用者(2000人),復購率穩定在20%左右。 **(2)回購率分析** ```python # 定義函式判斷使用者是否回購:本月消費,下月也消費,則表示使用者回購 def func_purchase(data): status = [] # 判斷前17個月 for i in range(data.count()-1): # 本月有消費 if data[i] > 0: # 下個月也消費,則為回購,即為1 if data[i+1] > 0: status.append(1) # 下個月不消費,不回購,記為0 else: status.append(0) # 本月無消費,賦予為NaN,count不統計 else: status.append(np.nan) # 最後一個月補充為NaN,因為沒有下一月資料,無法判斷是否回購 status.append(np.nan) return pd.Series(status,index=data.index) # axis=1,按行逐使用者傳入 purchase = pivoted_counts.apply(func_purchase,axis=1) purchase.head() ``` ![image](https://img2020.cnblogs.com/blog/2104707/202103/2104707-20210312153550501-1014619214.png) ```python # 計算回購率 purchase_rate = pd.DataFrame(purchase.sum()/purchase.count(),columns=['回購率']) purchase_rate.head() ``` ```python purchase_rate.plot(figsize=(10,4),title='回購率月趨勢圖') ``` 由回購率月趨勢圖可知: * 前三個月,新使用者湧入,新使用者回購率在16%左右,大部分新客戶只在當月購買了一次,新客戶質量不佳; * 後回購率穩定在30%左後,波動較大(10%之間) # 五、案