最近為了更好的看出用戶訪問(wèn)APP的路徑蒸绩,我研究了桑吉圖衙四,網(wǎng)上雖然有很多文章,但是都只是片面的講解患亿,實(shí)戰(zhàn)過(guò)程有很多坑需要避免传蹈,所以押逼,我總結(jié)了畫(huà)桑吉圖的血淚經(jīng)驗(yàn),給大家分享惦界。下面先看看桑吉圖的效果吧:
通過(guò)上面的圖挑格,我們能很清楚的看到,大部分用戶是主動(dòng)訪問(wèn)某寶首頁(yè)沾歪,然后在首頁(yè)分別訪問(wèn)了聚劃算以及使用了搜索功能漂彤,在聚劃算之后又訪問(wèn)了直播、每日大牌灾搏,最后跳出了挫望。是不是很清晰?
訪問(wèn)路徑和數(shù)據(jù)都是虛擬的狂窑,為了做這個(gè)案例而已媳板,大家后面可以使用自己公司的數(shù)據(jù)。
什么是桑吉圖
扇基圖(Sankey diagram)蛉幸,即桑基能量分流圖丛晦,也叫赊热遥基能量平衡圖。它是一種特定類型的流程圖烫沙,右圖中延伸的分支的寬度對(duì)應(yīng)數(shù)據(jù)流量的大小若锁,通常應(yīng)用于能源、材料成分斧吐、金融等數(shù)據(jù)的可視化分析。因1898年Matthew Henry Phineas Riall Sankey繪制的“蒸汽機(jī)的能源效率圖”而聞名仲器,此后便以其名字命名為“擅郝剩基圖”
在互聯(lián)分析的主要意義是,其可以很清楚的看清楚用戶訪問(wèn)APP的路徑乏冀,可視化用戶訪問(wèn)和跳出的重要節(jié)點(diǎn)蝶糯。
如何畫(huà)桑吉圖
畫(huà)桑吉圖主要有以下幾步
第一步:數(shù)據(jù)源
我習(xí)慣是數(shù)據(jù)先處理成以下結(jié)構(gòu):
附上數(shù)據(jù)源代碼用作練習(xí):
# 導(dǎo)入包
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from pyecharts.charts import Sankey
from pyecharts import options as opts
import pyecharts
#數(shù)據(jù)源
df = pd.DataFrame({
'第一個(gè)頁(yè)面': ['某寶首頁(yè)', '某寶首頁(yè)', '某寶首頁(yè)', '某寶首頁(yè)', '某寶首頁(yè)', '某寶首頁(yè)', '某寶首頁(yè)', '某寶首頁(yè)', '某寶首頁(yè)', '某寶消息頁(yè)', '某寶消息頁(yè)', '某寶消息頁(yè)'],
'第二個(gè)頁(yè)面': ['搜索', '搜索', '搜索', '搜索', '聚劃算', '聚劃算', '聚劃算', '聚劃算', '聚劃算', '交易物流', '交易物流', '活動(dòng)優(yōu)惠'],
'第三個(gè)頁(yè)面': ['歷史搜索', '歷史搜索', '搜索發(fā)現(xiàn)', '搜索發(fā)現(xiàn)', '每日大牌', '每日大牌', '直播', '直播', '直播', '物流詳情', '物流詳情', '權(quán)益過(guò)期提醒'],
'第四個(gè)頁(yè)面': ['搜索結(jié)果頁(yè)', '跳出', '搜索結(jié)果頁(yè)', '跳出', '物品詳情頁(yè)', '跳出', '觀看直播', '跳出', '我的頁(yè)面', '某旗艦店', '跳出', '跳出'],
'用戶量-萬(wàn)': [77, 706, 56, 981, 871, 348, 638, 698, 912, 651, 627, 380]
})
第二步:定義節(jié)點(diǎn)
什么節(jié)點(diǎn)呢?其實(shí)就是所有用戶訪問(wèn)頁(yè)面的名稱辆沦,用戶從頁(yè)面A到頁(yè)面B昼捍,再到C。把所有頁(yè)面都列出來(lái)肢扯。(可以看出使用了unique(),進(jìn)行去重妒茬,這個(gè)地方需要注意,后面會(huì)說(shuō))
代碼:
nodes = []
for i in range(0,4):
values = df.iloc[:,i].unique()
for value in values:
dic = {}
dic['name'] = value
nodes.append(dic)
結(jié)果:
第三步:定義邊和流量
什么是定義邊和流量呢蔚晨?其實(shí)就是把A到B和B到C具體的轉(zhuǎn)化量計(jì)算出來(lái)乍钻。
代碼一:代碼一的意義在于肛循,用戶訪問(wèn)路徑是復(fù)雜的,可能有10步如果银择,我們需要看前四步流轉(zhuǎn)情況的話多糠,就要先聚合前四步。
first = df.groupby(['第一個(gè)頁(yè)面','第二個(gè)頁(yè)面'])['用戶量-萬(wàn)'].sum().reset_index()
b = df.groupby(['第二個(gè)頁(yè)面','第三個(gè)頁(yè)面',])['用戶量-萬(wàn)'].sum().reset_index()
c = df.groupby(['第三個(gè)頁(yè)面','第四個(gè)頁(yè)面',])['用戶量-萬(wàn)'].sum().reset_index()
first.columns = ['source','target','value']
b.columns = ['source','target','value']
c.columns = ['source','target','value']
result = pd.concat([first,b,c])
result.head(10)
代碼二:
如果就是看所有頁(yè)面的話浩考,直接使用這個(gè)代碼就好夹孔。此時(shí)把result換成df就好了
linkes=[]
for i in result.values:
dic={}
dic['source']=i[0]
dic['target']=i[1]
dic['value']=i[2]
linkes.append(dic)
結(jié)果:
從這個(gè)結(jié)果就能看到每一步的流轉(zhuǎn),source是上一個(gè)頁(yè)面析孽,target是下一個(gè)頁(yè)面搭伤,value是從上一個(gè)頁(yè)面到下一個(gè)頁(yè)面的用戶量,比如紅色框代表從消息頁(yè)到交易物流頁(yè)面的用戶量是1278
第四步:畫(huà)圖
代碼:
畫(huà)圖就直接使用下面代碼就可以了绿淋,我們解釋一下:
- init_opts=opts.InitOpts(width="1300px", height="500px")闷畸,控制整個(gè)畫(huà)圖的大小,如果頁(yè)面比較多吞滞,那就需要比較大的畫(huà)圖區(qū)域佑菩,使用整個(gè)代碼進(jìn)行調(diào)參。
- label_opts=opts.LabelOpts(position='right')裁赠,是頁(yè)面名稱的顯示位置殿漠,比如上面的1處聚劃算,目前顯示在右側(cè)佩捞。
- node_gap=10,代表2處绞幌,聚劃算和搜索之間的間距,頁(yè)面少的時(shí)候一忱,可以調(diào)大間距莲蜘。
- node_width = 35,代表3處,是搜索柱子的粗細(xì)帘营。
-
focus_node_adjacency ='allEdges'票渠。是鼠標(biāo)懸停上面顯示高亮,可以看看開(kāi)篇時(shí)候鼠標(biāo)的效果芬迄。
pic=(
Sankey(init_opts=opts.InitOpts(width="1300px", height="500px"))
.add(
'',#圖例名稱
nodes,#傳入節(jié)點(diǎn)數(shù)據(jù)
linkes,#傳入邊和流量數(shù)據(jù)
#設(shè)置透明度问顷、彎曲度、顏色
linestyle_opt=opts.LineStyleOpts(opacity=0.3,curve=0.5,color='source'),
#標(biāo)簽顯示位置
label_opts=opts.LabelOpts(position='right'),
#節(jié)點(diǎn)之間的距離
node_gap=10,
#orient="vertical",#查看垂直圖片的操作
node_width = 35,
# 少魇幔基圖中節(jié)點(diǎn)的對(duì)齊方式杜窄,默認(rèn)是雙端對(duì)齊,可以設(shè)置為左對(duì)齊或右對(duì)齊算途,對(duì)應(yīng)的值分別是:# left: 節(jié)點(diǎn)左對(duì)齊塞耕。# right: 節(jié)點(diǎn)右對(duì)齊。# justify: 節(jié)點(diǎn)雙端對(duì)齊嘴瓤。
node_align = 'right',
# 距離右側(cè)的距離
#pos_right = "10%",
# 距離左側(cè)的距離
# pos_left = '1%',
#鼠標(biāo)懸停時(shí)荷科,節(jié)點(diǎn)高亮
focus_node_adjacency ='allEdges'
)
.set_global_opts(title_opts=opts.TitleOpts(title='用戶行為'))
)
pic.render('app_act.html')
注意點(diǎn)
- 主要是需要注意一點(diǎn)是第二步定義節(jié)點(diǎn)時(shí)唯咬,使用的unique(),這個(gè)是去重所有的頁(yè)面,但是有個(gè)場(chǎng)景就不能滿足畏浆,并且是90%以上不滿足:
- 比如用戶在第一個(gè)頁(yè)面訪問(wèn)之后就跳出了胆胰,那么為了保證數(shù)據(jù)結(jié)構(gòu),必須后面幾個(gè)頁(yè)面夠賦值跳出刻获。數(shù)據(jù)如下蜀涨,此時(shí)你使用上面的代碼是不能畫(huà)出圖。
數(shù)據(jù)源代碼
- 比如用戶在第一個(gè)頁(yè)面訪問(wèn)之后就跳出了胆胰,那么為了保證數(shù)據(jù)結(jié)構(gòu),必須后面幾個(gè)頁(yè)面夠賦值跳出刻获。數(shù)據(jù)如下蜀涨,此時(shí)你使用上面的代碼是不能畫(huà)出圖。
df1 = pd.DataFrame({
'第一個(gè)頁(yè)面': ['某寶首頁(yè)', '某寶首頁(yè)', '某寶消息頁(yè)', '某寶消息頁(yè)'],
'第二個(gè)頁(yè)面': ['搜索', '跳出', '交易物流', '跳出'],
'第三個(gè)頁(yè)面': ['歷史搜索', '跳出', '物流詳情', '跳出'],
'第四個(gè)頁(yè)面': ['搜索結(jié)果頁(yè)', '跳出', '跳出', '跳出'],
'用戶量-萬(wàn)': [145, 313, 699, 520]
})
那么我們需要進(jìn)行處理:
for i in range(0,4):
df.iloc[:,i] = df.iloc[:,i] + str(i)
結(jié)果:
然后就能使用后面的幾步:定義節(jié)點(diǎn)--定義邊和流量--畫(huà)圖蝎毡。
#定義節(jié)點(diǎn)
nodes = []
for i in range(0,4):
values = df1.iloc[:,i].unique()
for value in values:
dic = {}
dic['name'] = value
nodes.append(dic)
#定義邊和流量
first = df1.groupby(['第一個(gè)頁(yè)面','第二個(gè)頁(yè)面'])['用戶量-萬(wàn)'].sum().reset_index()
b = df1.groupby(['第二個(gè)頁(yè)面','第三個(gè)頁(yè)面',])['用戶量-萬(wàn)'].sum().reset_index()
c = df1.groupby(['第三個(gè)頁(yè)面','第四個(gè)頁(yè)面',])['用戶量-萬(wàn)'].sum().reset_index()
first.columns = ['source','target','value']
b.columns = ['source','target','value']
c.columns = ['source','target','value']
result = pd.concat([first,b,c])
linkes=[]
for i in result.values:
dic={}
dic['source']=i[0]
dic['target']=i[1]
dic['value']=i[2]
linkes.append(dic)
#畫(huà)圖
pic=(
Sankey(init_opts=opts.InitOpts(width="1300px", height="500px"))
.add(
'',#圖例名稱
nodes,#傳入節(jié)點(diǎn)數(shù)據(jù)
linkes,#傳入邊和流量數(shù)據(jù)
#設(shè)置透明度厚柳、彎曲度、顏色
linestyle_opt=opts.LineStyleOpts(opacity=0.3,curve=0.5,color='source'),
#標(biāo)簽顯示位置
label_opts=opts.LabelOpts(position='right'),
#節(jié)點(diǎn)之間的距離
node_gap=10,
#orient="vertical",#查看垂直圖片的操作
node_width = 35,
# 摄灞基圖中節(jié)點(diǎn)的對(duì)齊方式别垮,默認(rèn)是雙端對(duì)齊,可以設(shè)置為左對(duì)齊或右對(duì)齊扎谎,對(duì)應(yīng)的值分別是:# left: 節(jié)點(diǎn)左對(duì)齊碳想。# right: 節(jié)點(diǎn)右對(duì)齊。# justify: 節(jié)點(diǎn)雙端對(duì)齊毁靶。
node_align = 'right',
# 距離右側(cè)的距離
#pos_right = "10%",
# 距離左側(cè)的距離
# pos_left = '1%',
#鼠標(biāo)懸停時(shí)胧奔,節(jié)點(diǎn)高亮
focus_node_adjacency ='allEdges'
)
.set_global_opts(title_opts=opts.TitleOpts(title='用戶行為'))
)
pic.render('app_act.html')
結(jié)果:
寫(xiě)在最后:
大家一定要使用上面的數(shù)據(jù)進(jìn)行訓(xùn)練,體會(huì)其中的坑预吆。龙填。。
大家一定要使用上面的數(shù)據(jù)進(jìn)行訓(xùn)練拐叉,體會(huì)其中的坑岩遗。。凤瘦。
大家一定要使用上面的數(shù)據(jù)進(jìn)行訓(xùn)練喘先,體會(huì)其中的坑。廷粒。。