用實戰玩轉pandas資料分析(一)——使用者消費行為分析(python)
阿新 • • 發佈:2021-03-12
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%之間)
# 五、案