NK0*_*K09 6 python directed-graph plotly
我正在尝试为客户状态迁移制作有向图或桑基图(任何都可以)。数据如下所示,count 表示从当前状态迁移到下一个状态的用户数。
**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
Run Code Online (Sandbox Code Playgroud)
我编写了一个构建 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()
Run Code Online (Sandbox Code Playgroud)
Rol*_*ith 10
对于有向图,graphviz将是我选择的工具而不是 Python。
以下脚本txt2dot.py将您的数据转换为 graphviz 的输入文件:
text = '''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'''
# Remove ambiguity and make suitable for graphviz.
text = text.replace('New Profile', 'NewProfile')
text = text.replace('New ', 'NewProfile ')
text = text.replace('Profile Initiated', 'ProfileInitiated')
text = text.replace(' Initiated', ' ProfileInitiated')
# Create edges and nodes for graphviz.
edges = [ln.split() for ln in text.splitlines()]
edges = sorted(edges, key=lambda x: -1*int(x[2]))
nodes = sorted(list(set(i[0] for i in edges) | set(i[1] for i in edges)))
print('digraph foo {')
for n in nodes:
print(f' {n};')
print()
for item in edges:
print(' ', item[0], ' -> ', item[1], ' [label="', item[2], '"];', sep='')
print('}')
Run Code Online (Sandbox Code Playgroud)
运行python3 txt2dot.py > foo.dot结果:
digraph foo {
Applied;
End;
IntentDetected;
InterestedInJob;
JobRecommended;
NewProfile;
NotInterestedInJob;
NotOpted;
ProfileCreated;
ProfileInitiated;
NewProfile -> ProfileInitiated [label="37715"];
ProfileInitiated -> End [label="36411"];
JobRecommended -> End [label="6202"];
NewProfile -> End [label="6171"];
ProfileCreated -> JobRecommended [label="5799"];
ProfileInitiated -> ProfileCreated [label="4360"];
NewProfile -> NotOpted [label="3751"];
NotOpted -> ProfileInitiated [label="2817"];
JobRecommended -> InterestedInJob [label="2542"];
IntentDetected -> ProfileCreated [label="2334"];
ProfileCreated -> IntentDetected [label="1839"];
InterestedInJob -> Applied [label="1671"];
JobRecommended -> NotInterestedInJob [label="1477"];
NotInterestedInJob -> ProfileCreated [label="1408"];
IntentDetected -> End [label="1325"];
NotOpted -> End [label="1009"];
InterestedInJob -> ProfileCreated [label="975"];
Applied -> IntentDetected [label="912"];
NotInterestedInJob -> IntentDetected [label="720"];
Applied -> ProfileCreated [label="701"];
InterestedInJob -> End [label="673"];
}
Run Code Online (Sandbox Code Playgroud)
跑步dot -o foo.png -Tpng foo.dot给出: