Умножение и сложение весов - PullRequest
0 голосов
/ 04 января 2019

I ранее задавал вопрос о умножении на веса в сети x, чтобы найти общую долю узлов в ориентированном графе. Предоставленное решение хорошо работает, если между двумя узлами существует только один путь, но не работает, если путь больше. Простой пример:

import pandas as pd
data = pd.DataFrame({'shop': ['S1', 'S1', 'S2', 'S2', 'S3'],
                     'owner': ['S2', 'S3', 'O1', 'O2', 'O1'],
                     'share': [0.8,   0.2,  0.5,  0.5, 1.0]})
  owner  shop  share
0    S2   S1    0.8
1    S3   S1    0.2
2    O1   S2    0.5
3    O2   S2    0.5
4    O1   S3    1.0

создать график:

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

Чтобы получить долю O1 в S1, необходимо умножить 2 пути и затем добавить их. Предыдущее решение не может этого сделать. Есть ли способ сделать это?

1 Ответ

0 голосов
/ 04 января 2019

Вы можете изменить предыдущее решение следующим образом:

from operator import mul

import pandas as pd
import networkx as nx
from functools import reduce

data = pd.DataFrame({'shop': ['S1', 'S1', 'S2', 'S2', 'S3'],
                     'owner': ['S2', 'S3', 'O1', 'O2', 'O1'],
                     'share': [0.8,   0.2,  0.5,  0.5, 1.0]})

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

owners = set(data['owner'])
shops  = set(data['shop'])


result = []
summary = {}
for shop in shops:
    for owner in owners:
        for path in nx.all_simple_paths(G, shop, owner):
            share = reduce(mul, (G[start][end]['share'] for start, end in zip(path[:-1], path[1:])), 1)
            summary[(owner, shop)] = summary.get((owner, shop), 0) + share


summary = pd.DataFrame.from_dict(summary, orient = 'index', columns = 'share'.split())
print(summary)

выход

          share
(O2, S2)    0.5
(O2, S1)    0.4
(S3, S1)    0.2
(O1, S2)    0.5
(O1, S3)    1.0
(O1, S1)    0.6
(S2, S1)    0.8

Линия:

share = reduce(mul, (G[start][end]['share'] for start, end in zip(path[:-1], path[1:])), 1)

вычисляет долю для определенного пути. Затем эта доля агрегируется по всем путям с использованием следующей строки:

summary[(owner, shop)] = summary.get((owner, shop), 0) + share
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...