數(shù)據(jù)分析---單車消費(fèi)情況實(shí)戰(zhàn)文字總結(jié)

讀取數(shù)據(jù)

分隔符

read_csv(sep='s+')

轉(zhuǎn)化為日期格式

pd.to_datetime(一列, format("%Y%m%d"))

日期只保留月份

只有ndarray、series都可以使用astype方法,所以需要values取得對(duì)應(yīng)的array

df['dt‘].values.astype('datetime64[M]')

df['dt'].astype('datetime64[M]') 得到的結(jié)果相同

這樣可以幫助我們按月匯總

月消費(fèi)趨勢(shì)分析

月消費(fèi)總額求和

df.groupby('month').order_amount.sum()

對(duì)多個(gè)字段匯總計(jì)算

agg需要傳入一個(gè)字典

df['am', 'user_id', 'pro_count'].agg({'am':'sum', user_id:count, pro_count:sum})

重置索引

reset_index 可以把索引month列變?yōu)橐粋€(gè)普通的列

修改列名

修改列名,傳入columns參數(shù)【是一個(gè)字典】

對(duì)一個(gè)列去重

df.user_id.unique()

對(duì)每一組去重

grouped_info :dfgroupedby類型

grouped_info[A]:dfseries類型 可以在上面施加 .unique() 方法

apply方法使用注意事項(xiàng)

  • 凡是可以在對(duì)象上 .出來(lái)的函數(shù),例如unique(),astype() 方法。都可以直接在矢量上面 .出來(lái)

  • 凡是可以接受一個(gè)對(duì)象作為入?yún)⒌暮瘮?shù),都可以通過(guò)apply施加到 矢量上面。例如:sum,len, str等方法

  • 相對(duì)于apply來(lái)講,map更加的輕量,一般用在字符串格式化等場(chǎng)合,施加函數(shù)的話 apply更適合

  • 如果函數(shù)不想單獨(dú)寫(xiě)的話,可以把lambda表達(dá)式傳給 apply

  • 有些函數(shù)既可以點(diǎn)出來(lái),又可以把對(duì)象作為入?yún)?,這種情況下 矢量直接點(diǎn)和apply效果一樣,如下例:

    image-20200628105553828

pandas日期在powerBI中展示日期

grouped_info_agg['month'] = grouped_info_agg['month'].astype(str)

不然在powerBI中會(huì)變成時(shí)間戳,,字符串的話傳入字后是年月日

數(shù)據(jù)透視表

相當(dāng)于少寫(xiě)了一步groupby并且篩選列的 代碼,但是個(gè)人還是喜歡一步一步來(lái)。

df.pivot_table(index=month,

values=[am, user_id, pro_count],

aggfunc={am:sum, user_id:count, pro_count:sum})

用戶個(gè)體消費(fèi)分析

消費(fèi)金額和次數(shù)的關(guān)系

groupby('user_id').sum() 會(huì)自動(dòng)幫我們求和 pro_count,order_amount 這種字段

describe分析

對(duì)sum() 直接describe可以看到每個(gè)用戶的平均值等

趨勢(shì)線擬合

金額和數(shù)量的關(guān)系

在分析 tab里面

對(duì)于干擾性的極值,我們可以用篩選器取出

分布情況

pd.cut

用到了列表生成區(qū)間: list = [i for i in range(0, max+50, 50)]

bins=list

或者 bins=100 直接寫(xiě)數(shù)量也可以,但是會(huì)出現(xiàn)小數(shù),所以一般用列表

labels數(shù)組比bins數(shù)組長(zhǎng)度少1

極值的篩選:切比雪夫不等式

95%的數(shù)據(jù)在5個(gè)標(biāo)準(zhǔn)差之內(nèi)。

消費(fèi)累計(jì)百分比

grouped_user_info.order_amount 這時(shí)候是seriesgroupby的類型

對(duì)其sum一下子就是series了。

排序

sort_values('列名')

對(duì)df施加apply

其實(shí)是對(duì)于每一列施加。

df.apply(lambda x:x.cumsum()/x.sum())

cumsum的展示注意

需要重置索引,保證索引是遞增的,否則會(huì)跳動(dòng)

中值線

會(huì)把自變量 從中間分

可以幫我們驗(yàn)證28法則。

在運(yùn)營(yíng)上我們應(yīng)該抓大放小

用戶消費(fèi)行為

每個(gè)月份多少新增

user_first_dt = groupby('user_id').order_dt.min()

再groupby(order_dt)可以得到每個(gè)月有多少新用戶

再value_counts可以得到每個(gè)月的用戶數(shù)。

image-20200628121033368

此時(shí)可以reset_index就會(huì)變成一個(gè)df,然后df.dt.astype(str)否則在powerBI中會(huì)變成時(shí)間戳。

每個(gè)月用戶的流失

最后一天

新老用戶的消費(fèi)比

is_only_buy_one = grouped_user.dt.min==grouped_user.dt.max.

image-20200628122015484

每月的新客占比

groupby(user_id).min():得到每個(gè)用戶的第一天

groupby(user_id, month).min():得到該用戶在本月的第一天

RFM模型

groupby(user_id), order_date->max, product_num->sum, order_amount->sum;

日期歸一化

rfm.order_dt - rfm.order_dt.max / np.timedelta64(1, 'D')可以知道差距多少天

這個(gè)日期作為R,order_product->F, order_amount->M.

先算出來(lái)是否大于均值

rfm.apply(lambda x:x-x.mean())

根據(jù)正負(fù)關(guān)系打標(biāo)簽

傳入x

x = x.apply(lambda x:'1' if x>0 else '0') #這是每個(gè)數(shù)值變成了字符類型

ret=x.R+x.F+x.M

就可以為ret定義一個(gè)字典

d={111:重要價(jià)值客戶,

011:重要保持客戶,

101:重要發(fā)展客戶,

001:重要挽留用戶,

110:一般價(jià)值客戶,

010:一般保持客戶,

100:一般發(fā)展客戶,

000:一般挽留用戶}

根據(jù)A列修改B列

rfm.loc[rfm.label=='重要價(jià)值客戶', ’color‘]='重要價(jià)值客戶’

rfm.loc[~(rfm.label='重要價(jià)值客戶'), ’color‘]='重要價(jià)值客戶’

還有里面取反的方式需要注意

用戶生命周期

用戶狀態(tài)的定義

非用戶---新--活躍

? -- 不活躍--回流

? --流失

user_id, month 的數(shù)據(jù)透視表

數(shù)據(jù)透視表

高端應(yīng)用: index=user_id, columns=month, aggfunc={'order_dt':'count'}

這么用的時(shí)候會(huì)出現(xiàn)multiindex多重索引,如果只想要一重索引,應(yīng)該用

values=order_dt, aggfunc=count

applymap

應(yīng)該到每個(gè)元素

每個(gè)月?tīng)顟B(tài)的計(jì)算

def active_status(user):
    ret = [];
    for i in range(0, 18):
        if (user[i]==0):
            if (len(ret) == 0):
                ret[i] = 'unreg';
            else 
                if (ret[i-1]=='unreg'):
                    ret[i] = 'unreg'
                else
                    ret[i] = 'unactive'
        else:
            if (len(ret) == 0):
                ret[i] = 'new'
            else:
                if (ret[i-1]=='unreg'):
                    ret[i] = 'new'
                else:
                    if (ret[i-1]=='unactive'):
                        ret[i] = 'return'
                    else:
                        ret[i] = 'active'
    return ret;

用戶關(guān)聯(lián)月定位0,1 表示該月是否購(gòu)買(mǎi)。

apply上面的狀態(tài)函數(shù),轉(zhuǎn)為 unreg, new, active, unactive, return 五個(gè)子狀態(tài)

unreg-->替換為np.nan

每一列value_counts就得到每個(gè)月有多少新用戶,不活躍,活躍

NaN的使用

  • 我們不希望統(tǒng)計(jì)未注冊(cè)用戶的數(shù)量,所以我們弄成NaN
  • 當(dāng)根據(jù)總數(shù)計(jì)算完畢 每種用戶的比例,我們又需要作圖0填充,就把NaN去掉

復(fù)購(gòu)率的計(jì)算

可以通過(guò)函數(shù)實(shí)現(xiàn) applymap(x: 1 if x>1 else 0 if x==0 else np.nan)

然后x.sum() / x.count() 得到復(fù)購(gòu)率

回購(gòu)率的計(jì)算

def cal_huigou:
    t = x>0 # 表示是否購(gòu)買(mǎi)
    return t.shift & t # 表示連續(xù)都買(mǎi)了,才算作回購(gòu)
df.apply(cal_huigou)

報(bào)告的路徑如下:
https://zhuanlan.zhihu.com/p/151789421

?

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容