Pytanie Najlepsze praktyki dotyczące kwerendy wykresów według krawędzi i atrybutów węzła w NetworkX


Korzystanie z NetworkX i nowości w bibliotece dla zapytania analizy sieci społecznościowej. Przez Query, mam na myśli wybierz / utwórz podgrafy według atrybutów obu węzłów krawędzi, gdzie krawędzie tworzą ścieżkę, a węzły zawierają atrybuty. Wykres wykorzystuje MultiDiGraph formularza

G2 = nx.MultiDiGraph()
G2.add_node( "UserA", { "type" :"Cat" } )
G2.add_node( "UserB", { "type" :"Dog" } )
G2.add_node( "UserC", { "type" :"Mouse" } )
G2.add_node( "Likes", { "type" :"Feeling" } )
G2.add_node( "Hates", { "type" :"Feeling" } )

G2.add_edge( "UserA", 'Hates' ,  statementid="1" )
G2.add_edge( "Hates", 'UserB' ,  statementid="1"  )
G2.add_edge( "UserC", 'Hates' ,  statementid="2" )
G2.add_edge( "Hates", 'UserA' ,  statementid="2"  )
G2.add_edge( "UserB", 'Hates' ,  statementid="3"  )
G2.add_edge( "Hates", 'UserA' ,  statementid="3"  )
G2.add_edge( "UserC", 'Likes' ,  statementid="3"  )
G2.add_edge( "Likes", 'UserB' ,  statementid="3"  )

Zapytano o

for node,data in G2.nodes_iter(data=True):
    if ( data['type'] == "Cat" ):
       # get all edges out from these nodes
            #then recursively follow using a filter for a specific statement_id

#or get all edges with a specific statement id
   # look for  with a node attribute of "cat" 

Czy istnieje lepszy sposób na zapytanie? A może najlepiej tworzyć niestandardowe iteracje, aby tworzyć podgrafy?

Alternatywnie (i osobne pytanie), wykres można uprościć, ale nie korzystam z poniższego wykresu, ponieważ obiekty typu "nienawiści" będą miały predyktorów. Czy to sprawi, że wyszukiwanie będzie łatwiejsze? Łatwiej jest iterować nad węzłami

G3 = nx.MultiDiGraph()
G3.add_node( "UserA", { "type" :"Cat" } )
G3.add_node( "UserB", { "type" :"Dog" } )

G3.add_edge( "UserA", 'UserB' ,  statementid="1" , label="hates")
G3.add_edge( "UserA", 'UserB' ,  statementid="2" , label="hates")

Inne notatki:

  • Być może add_path dodaje identyfikator do utworzonej ścieżki?
  • iGraph ma za dobra funkcja zapytania  g.vs.select()

19
2018-03-26 18:26


pochodzenie




Odpowiedzi:


Opierając się na Odpowiedź @ Aricamożesz znaleźć czerwoną rybę w ten sposób:

red_fish = set(n for u,v,d in G.edges_iter(data=True)
               if d['color']=='red'
               for n in (u, v)
               if G.node[n]['label']=='fish')

print(red_fish)
# set([2])

9
2018-03-27 10:17





Łatwo jest napisać jednoelement, aby utworzyć listę lub generator węzłów o określonej właściwości (pokazane tutaj generatory)

import networkx as nx

G = nx.Graph()
G.add_node(1, label='one')
G.add_node(2, label='fish')
G.add_node(3, label='two')
G.add_node(4, label='fish')

# method 1
fish = (n for n in G if G.node[n]['label']=='fish')
# method 2
fish2 = (n for n,d in G.nodes(data=True) if d['label']=='fish')

print(list(fish))
print(list(fish2))

G.add_edge(1,2,color='red')
G.add_edge(2,3,color='blue')

red = ((u,v) for u,v,d in G.edges(data=True) if d['color']=='red')

print(list(red))

Jeśli Twój wykres jest duży i poprawny, a chcesz szybko wyszukiwać, możesz utworzyć "odwrotny słownik" takich atrybutów,

labels = {}
for n, d in G.nodes(data=True):
    l = d['label']
    labels[l] = labels.get(l, [])
    labels[l].append(n)
print labels

21
2018-03-27 04:14



Przykłady wydają się być dobrym sposobem sprawdzenia węzłów lub krawędzi. Ale aby wyszukać kombinację węzłów i krawędzi? W twoim przykładzie wyobraź sobie zapytanie. "Zwróć podgrafę węzłów ryb, które również mają krawędź z atrybutem" Kolor = czerwony ". Czy istnieje również jedna linijka do wysłania zapytania do obu i przeszukiwania podgraphów? Np. Czy edges_iter zwraca oba węzły i krawędzie? - Jonathan Hendler


Aby wybrać krawędzie na podstawie atrybutów krawędzi ORAZ węzłów, możesz chcieć zrobić coś takiego, używając swojego wykresu, G2:

def select(G2, query):
    '''Call the query for each edge, return list of matches'''
    result = []
    for u,v,d in G2.edges(data=True):
        if query(u,v,d):
            result.append([(u,v)])
    return result

# Example query functions
# Each assumes that it receives two nodes (u,v) and 
# the data (d) for an edge 

def dog_feeling(u, v, d):
    return (d['statementid'] == "3" 
            and G2.node[u]['type'] == "Dog"
            or G2.node[u]['type'] == "Dog")

def any_feeling(u,v,d):
    return (d['statementid'] == "3" 
            and G2.node[u]['type'] == "Feeling"
            or G2.node[u]['type'] == "Feeling")

def cat_feeling(u,v,d):
    return (G2.node[u]['type'] == "Cat"
            or G2.node[v]['type'] == "Cat")

# Using the queries
print select(G2, query = dog_feeling)
print select(G2, query = any_feeling)
print select(G2, query = cat_feeling)

To redukuje proces iteracji do select() i możesz pisać swoje zapytania jako indywidualne, sprawdzalne funkcje.


7
2018-03-27 08:41