Best practices for Querying graphs by edge and node attributes in NetworkX

前端 未结 3 732
野性不改
野性不改 2020-12-04 11:38

Using NetworkX, and new to the library, for a social network analysis query. By Query, I mean select/create subgraphs by attributes of both edges nodes where the edges creat

相关标签:
3条回答
  • 2020-12-04 11:57

    It's pretty straightforward to write a one-liner to make a list or generator of nodes with a specific property (generators shown here)

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

    If your graph is large and fixed and you want to do fast lookups you could make a "reverse dictionary" of the attributes like this,

    labels = {}
    for n, d in G.nodes(data=True):
        l = d['label']
        labels[l] = labels.get(l, [])
        labels[l].append(n)
    print labels
    
    0 讨论(0)
  • 2020-12-04 12:08

    In order to select edges based on attributes of edges AND nodes, you may want to do something like this, using your graph, 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)
    

    This abstracts away the iteration process into the select() function and you can write your queries as individual, testable functions.

    0 讨论(0)
  • 2020-12-04 12:22

    Building on @Aric's answer, you can find red fish like this:

    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])
    
    0 讨论(0)
提交回复
热议问题