简体   繁体   中英

Multiplying Weights in Networkx Python

I am graphing a tree in networkx, and have added percentage shares as weights. Example: shops and owners of the shops, which can be another shop:

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

I can create a directed graph in networkx like this:

import networkx as nx    
G = nx.from_pandas_edgelist(data,'shop','owner',edge_attr = ('share'), 
create_using=nx.DiGraph())

And graph the result:

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')

在此处输入图片说明

How would I multiply the weights for each shop in the graph such that I have the owner and the percentage share? Something like the following:

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]})

output

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

Update: thanks to this question here I can get the product (multiplied weights) between any 2 chosen nodes (see below) How do I then get the same for all nodes in a data frame as above?

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'] 

Edit: misunderstood the question. Here is a possible answer:

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)

Output:

           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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM