python數(shù)據(jù)分析項目——臺北101門票銷售情況(二)

用戶分層

緊接著上一篇文章,現(xiàn)在我們來分析下不同用戶(游客)的分層:

user_status = df.pivot_table(index='author', columns='month', values='frequency', aggfunc='count')
user_status = user_status.fillna(0)
user_status = user_status.applymap(lambda x: 1 if x > 0 else 0)

建立一個數(shù)據(jù)透視表,并先將所有的NAN值改成0,購買過2次及以上的游客統(tǒng)統(tǒng)記為1,為接下來的用戶分層做準備:


3.png
def active_status(x):
    status = []
    for i in range(len(user_status.columns)):
        # 本月沒有消費
        if x[i] == 0:
            if len(status) > 0:
                if status[i-1] == 'unreg':
                    status.append('unreg')
                else:
                    status.append('unactive')
            else:
                status.append('unreg')
                
        # 本月有消費
        else:
            if len(status) == 0:
                status.append('new')
            else:
                if status[i-1] == 'unactive':
                    status.append('return')
                elif status[i-1] == 'unreg':
                    status.append('new')
                else:
                    status.append('active')
                    
    return pd.Series(status)

上面的代碼就是對用戶的簡單分層:'unreg'是個前期標注,表示非客戶;‘unactive'表示非活躍用戶,上月有消費,而本月沒有消費;'new'表示新客戶,之前沒有消費,本月有消費;'active'表示活躍用戶,連續(xù)兩月有消費;'return'表示回流用戶,本來的非活躍用戶,本月有消費。

pivot_user_status = user_status.apply(active_status, axis=1)
pivot_user_status.columns = user_status.columns
# 把浮點轉(zhuǎn)成整數(shù)
def convert_int(x):
    if isinstance(x, float) and x >= 0:
        return int(x)
# 將前期標注的'unreg'替換成NAN,不計入后續(xù)計算中,T表示index和columns的互換
pivot_user_status = pivot_user_status.replace('unreg', np.NAN).apply(pd.value_counts).T
pivot_user_status_count = pivot_user_status.fillna(0).applymap(convert_int)

上述的變換后,最后得到4種用戶每個月的購買情況:


4.png
plt.style.use('seaborn-pastel')
pivot_user_status_count.plot.area()
plt.title('用戶分層數(shù)量', fontsize=15)
plt.xlabel('月份', fontsize=12)
plt.ylabel('人數(shù)', fontsize=12)
plt.savefig('用戶分層數(shù)量area.png')
用戶分層數(shù)量area.png

從圖中可以看到活躍和回流用戶幾乎沒有,新用戶在2018年5月之后開始趨于穩(wěn)定,而這個時間點也是上篇文章中分析到的銷量明顯下降的日期;不活躍用戶隨著時間的積累,曲線符合預期,無異常。

而數(shù)據(jù)分析中,數(shù)量的指標遠不如比率的指標,所以我們再將4種用戶的數(shù)量改成比率,這樣才能更直觀地看出問題和端倪:

rate = pivot_user_status_count.apply(lambda x: x/x.sum()).applymap(lambda x: float('%.3f' % x))
plt.style.use('fast')
titles = rate.columns.values
labels = (i for i in rate.columns.values)
plt.figure(figsize=(20,10))
plt.subplots_adjust(hspace=0.5)
for x in range(4):
    plt.subplot(f'22{x}')
    rate.loc[:,next(labels)].plot()
    plt.xlabel('月份', fontsize=10)
    plt.ylabel(f'{titles[x]}比例', fontsize=10)
    plt.title(f'{titles[x]}用戶比例', fontsize=12)
plt.savefig('各層用戶比例plot.png')
各層用戶比例plot.png

可以看到門票的銷售情況,在2018年5月之后,逐步上升,不管是新用戶,還是回流,還是活躍。

用戶生命周期

time_max = df.groupby('author').time.max()
time_min = df.groupby('author').time.min()
lfc = (time_max - time_min).reset_index()
5.png

通過簡單的描述能夠看到,平均的生命周期只有23天,由于上篇文章中分析到的,92%的用戶是一次消費用戶,所以平均生命周期很短,因此下面我們?nèi)コ淮蜗M,分析下二次及以上消費的生命周期:

lfc['lifetime'] = lfc.time/np.timedelta64(1,'D')

plt.figure(figsize=(10,5))
sns.distplot(lfc[lfc['lifetime'] > 0].lifetime, kde=False, rug=False, bins=50, color=sns.xkcd_rgb['brick red'])
plt.title('二次消費以上用戶生命周期', fontsize=15, pad=10)
plt.xlabel('天數(shù)', fontsize=12, labelpad=5)
plt.ylabel('人數(shù)', fontsize=12, labelpad=5)
plt.savefig('二次消費以上用戶生命周期hist.png')
二次消費以上用戶生命周期hist.png

6.png

結合密度圖和均值,能看到二次及以上消費的生命周期拉長到了300天,整體趨勢隨著時間的流逝而下降。

留存率

user_retention = pd.merge(left=df, right=time_min.reset_index(), how='inner', on='author', suffixes=('', '_min')).drop(columns=['year','rating','amount'])
user_retention['timediff'] = user_retention.time - user_retention.time_min
user_retention['timediff'] = user_retention.timediff.apply(lambda x: x/np.timedelta64(1,'D'))

bins = []
for i in range(0, 1000, 100):
    bins.append(i)
user_retention['timediff_bin'] = pd.cut(user_retention['timediff'], bins=bins)
user_r_tran = user_retention.groupby(['author', 'timediff_bin']).frequency.sum().unstack()
user_r_tran = user_r_tran.fillna(0).applymap(lambda x: 1 if x > 0 else 0)
vals = [float('%.2f'%i) for i in ((user_r_tran.sum()/user_r_tran.count()).values)]

plt.figure(figsize=(10,5))
sns.barplot(user_r_tran.columns.values, vals, palette='PuRd_r')
plt.title('各時間段的用戶留存率', fontsize=12, color=sns.xkcd_rgb['reddish'], pad=10)
plt.xlabel('時間跨度(天)', fontsize=10, color=sns.xkcd_rgb['reddish'])
plt.ylabel('留存比率', fontsize=10, color=sns.xkcd_rgb['reddish'])
plt.xticks(rotation=90)
for px, py in zip(range(9), vals):
    plt.text(px-0.2,py+0.004,f'{py}')
plt.savefig('各時間段的用戶留存率bar.png')
各時間段的用戶留存率bar.png

留存率的計算方式就是以100天為一階段,購買的用戶/總用戶,我們可以看到時間跨度越大,留存率越低;臺北101門票更多的還是依靠新用戶的消費。針對用戶留存問題,不建議過多關注。

def diff(x):
    return abs(x.timediff - x.timediff.shift(-1))
lastdiff = user_retention.groupby('author').apply(diff)
plt.figure(figsize=(10,5))
sns.distplot(lastdiff.dropna(), kde=False, color=sns.xkcd_rgb['pure blue'])
plt.title('重復購買的周期', fontsize=12, color=sns.xkcd_rgb['reddish'], pad=10)
plt.xlabel('天數(shù)', fontsize=10, color=sns.xkcd_rgb['reddish'], labelpad=6)
plt.ylabel('人數(shù)', fontsize=10, color=sns.xkcd_rgb['reddish'], labelpad=6)
plt.savefig('重復購買的周期distplot.png')
重復購買的周期distplot.png

針對二次及以上消費的用戶購買周期分析可以發(fā)現(xiàn),這是個典型的頭長尾短的圖形,也就意味著該類型的產(chǎn)品,是適合一次性消費的購物習慣,和我們上面的留存率,用戶分層的分析相符合。

總結:

本次的數(shù)據(jù)分析項目主要的目的之一是針對零售、電商、移動互聯(lián)網(wǎng)中經(jīng)常出現(xiàn)的一些指標的分析:復購率、留存率、用戶分層、用戶生命周期、購買周期。鍛煉針對時間類型數(shù)據(jù)的處理。

?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內(nèi)容