Умножение весов в Networkx Python - PullRequest
0 голосов
/ 07 декабря 2018

Я строю график дерева в 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

Я могу создать ориентированный граф в сети x, например:

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

enter image description here

Как бы я умножил веса для каждого магазина на графике, чтобы у меня был владелец и процентная доля?Что-то вроде следующего:

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

Обновление: благодаря этому вопросу здесь Я могу получить продукт (умноженные веса) между любыми 2 выбраннымиузлы (см. ниже) Как мне получить то же самое для всех узлов в кадре данных, как указано выше?

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

1 Ответ

0 голосов
/ 10 декабря 2018

Редактировать: неправильно понял вопрос.Вот возможный ответ:

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...