我正在networkx中绘制一棵树,并增加了权重百分比。例如:商店和商店的所有者,可以是另一家商店:
import pandas as pd
data = pd.DataFrame({'shop': ['S1', 'S1', 'S1', 'S2', 'S2', 'S3', 'S3', 'S3'],
'owner': ['O1', 'O2', 'S2', 'S3', 'O3', 'O4', 'O5', 'O6'],
'share': [0.2, 0.2, 0.6, 0.5, 0.5, 0.1, 0.1, 0.8]})
data
shop owner share
S1 O1 0.2
S1 O2 0.2
S1 S2 0.6
S2 S3 0.5
S2 O3 0.5
S3 O4 0.1
S3 O5 0.1
S3 O6 0.8
我可以像这样在networkx中创建一个有向图:
import networkx as nx
G = nx.from_pandas_edgelist(data,'shop','owner',edge_attr = ('share'),
create_using=nx.DiGraph())
并绘制结果图形:
pos=nx.spring_layout(G, k = 0.5, iterations = 20)
node_labels = {node:node for node in G.nodes()}
nx.draw_networkx(G, pos, labels = node_labels, arrowstyle = '-|>',
arrowsize = 20, font_size = 15, font_weight = 'bold')
如何将图中每个商店的权重相乘,以便拥有所有者和所占的百分比?类似于以下内容:
output = pd.DataFrame({'shop': ['S1', 'S1', 'S1', 'S1', 'S1', 'S1', 'S2',
'S2', 'S2','S2', 'S3', 'S3', 'S3'],
'owner': ['O1', 'O2', 'O3', 'O4', 'O5', 'O6', 'O3',
'O4', 'O5','O6', 'O4', 'O5', 'O6'],
'share': [0.2, 0.2, 0.3, 0.03, 0.03, 0.24, 0.5, 0.05,
0.05, 0.4, 0.1, 0.1, 0.8]})
输出
shop owner share
S1 O1 0.2
S1 O2 0.2
S1 O3 0.3
S1 O4 0.03
S1 O5 0.03
S1 O6 0.24
S2 O3 0.5
S2 O4 0.05
S2 O5 0.05
S2 O6 0.4
S3 O4 0.1
S3 O5 0.1
S3 O6 0.8
更新:由于这个问题here,我可以得到任意两个选定节点之间的乘积(乘以权重)(请参见下文),然后如何为上述数据框中的所有节点获得相同的结果? / p>
start = 'S1' # start node
end = 'O5' # end node
all_paths = [path for path in nx.all_simple_paths(G, start, end)]
for p in all_paths: # keep track of each path
for _ in range(len(p)): # for each node in this path
pairs = zip(p, p[1:]) # get sequence of nodes
product = 1
for pair in pairs: # for each pair of nodes in this path
an_edge = G.get_edge_data(pair[0], pair[1])
product *= an_edge['share']
答案 0 :(得分:1)
编辑:误解了这个问题。这是一个可能的答案:
owners = set(data['owner'])
shops = set(data['shop'])
summary = {}
for owner in owners:
for shop in shops:
paths = list(nx.all_simple_paths(G, shop, owner))
if len(paths):
for path in paths:
for start, end in zip(path[:-1], path[1:]):
summary[(shop, owner)] = summary.get((shop,owner), 1) * G[start][end]['share']
summary = pd.DataFrame.from_dict(summary, orient = 'index', columns = 'share'.split())
print(summary)
输出:
share
(S2, O4) 0.05
(S3, O4) 0.10
(S1, O4) 0.03
(S2, O6) 0.40
(S3, O6) 0.80
(S1, O6) 0.24
(S2, O5) 0.05
(S3, O5) 0.10
(S1, O5) 0.03
(S1, O2) 0.20
(S2, S3) 0.50
(S1, S3) 0.30
(S1, S2) 0.60
(S2, O3) 0.50
(S1, O3) 0.30
(S1, O1) 0.20