私は、顧客の状態を移行するための有向グラフまたはSankeyダイアグラム(どれでも機能します)を作成しようとしています。データは以下のようになります。カウントは、現在の状態から次の状態に移行するユーザーの数を意味します。
**current_state next_state count**
New Profile Initiated 37715
Profile Initiated End 36411
JobRecommended End 6202
New End 6171
ProfileCreated JobRecommended 5799
Profile Initiated ProfileCreated 4360
New NotOpted 3751
NotOpted Profile Initiated 2817
JobRecommended InterestedInJob 2542
IntentDetected ProfileCreated 2334
ProfileCreated IntentDetected 1839
InterestedInJob Applied 1671
JobRecommended NotInterestedInJob 1477
NotInterestedInJob ProfileCreated 1408
IntentDetected End 1325
NotOpted End 1009
InterestedInJob ProfileCreated 975
Applied IntentDetected 912
NotInterestedInJob IntentDetected 720
Applied ProfileCreated 701
InterestedInJob End 673
Sankeyを構築するコードを記述しましたが、プロットは簡単に読み取ることができません。読みやすい有向グラフを探しています。これが私のコードです:
df = pd.read_csv('input.csv')
x = list(set(df.current_state.values) | set(df.next_state))
di = dict()
count = 0
for i in x:
di[i] = count
count += 1
#
df['source'] = df['current_state'].apply(lambda y : di[y])
df['target'] = df['next_state'].apply(lambda y : di[y])
#
fig = go.Figure(data=[go.Sankey(
node = dict(
pad = 15,
thickness = 20,
line = dict(color = "black", width = 0.5),
label = x,
color = "blue"
),
link = dict(
source = df.source,
target = df.target,
value = df['count']
))])
#
fig.update_layout(title_text="Sankey Diagram", font_size=10, autosize=False,
width=1000,
height=1000,
margin=go.layout.Margin(
l=50,
r=50,
b=100,
t=100,
pad=4
))
fig.show()
これにより、次のことを前提として、基本的なSankey図が作成されます。
2と3は、先史時代以外のテキストエディター、またはpython自体、大量のデータの場合でも簡単に実行できます。引用符で囲まれていない値で空白を使用しないことを強くお勧めします。
import plotly.graph_objects as go
import numpy as np
import matplotlib
if __name__ == '__main__':
with open('state_migration.csv', 'r') as finput:
info = [[ _ for _ in _.strip().lower().split(',') ]
for _ in finput.readlines()[1:]]
info_t = [*map(list,Zip(*info))] # info transposed
# this exists to map the data to plotly's node indexing format
index = {n: i for i, n in enumerate(set(info_t[0]+info_t[1]))}
fig = go.Figure(data=[go.Sankey(
node = dict(
pad = 15,
thickness = 20,
line = dict(color = "black", width = 0.5),
label = list(index.keys()),
color = np.random.choice( list(matplotlib.colors.cnames.values()),
size=len(index.keys()), replace=False )
),
link = dict(
source = [index[_] for _ in info_t[0]],
target = [index[_] for _ in info_t[1]],
value = info_t[2]
))])
fig.update_layout(title_text="State Migration", font_size=12)
fig.show()
ノードをドラッグできます。位置を事前に定義したり、他のパラメーターを確認したりする場合は、 this を参照してください。
私が使用したデータは、あなたの入力のクリーンなバージョンでした:
currentstate,next_state,count
new,initiated,37715
profileinitiated,end,36411
jobrecommended,end,6202
new,end,6171
profilecreated,jobrecommended,5799
profileinitiated,profilecreated,4360
new,notopted,3751
notopted,profileinitiated,2817
jobrecommended,interestedinjob,2542
intentdetected,profilecreated,2334
profilecreated,intentdetected,1839
interestedinjob,applied,1671
jobrecommended,notinterestedinjob,1477
notinterestedinjob,profilecreated,1408
intentdetected,end,1325
notopted,end,1009
interestedinjob,profilecreated,975
applied,intentdetected,912
notinterestedinjob,intentdetected,720
applied,profilecreated,701
interestedinjob,end,673
ダイアグラムが奇妙だったので、「新しいプロファイル」を既存の状態「新しい」に変更しました。必要に応じて自由に調整してください。
私が使用したライブラリーは、あなたが望むものに絶対に必要というわけではありません。私はそれらに慣れているだけです。有向グラフについては、Roland Smithがカバーしています。また、Plotlyを使用して行うこともできます。その gallery を参照してください。
Python 3.8.1でテスト済み
condekindは答えがカバーされているように見えますが...パンダを使用しているので、これらの以前の答えは、データを整理して図を作成する実用的な側面に役立ちます。
pandas dataframe? を使用してサンキーダイアグラムの構造を定義する方法
および alishobeiri には、使用できるいくつかの便利な例とコードがあります。 https://plot.ly/~alishobeiri/1591/plotly-sankey-diagrams/#/
plot.ly documentation とともに、ノード配置の特定の質問に答えます。
Sankey図が散らかっている場合は、水平方向ではなく垂直方向を試すこともできます。