【问题标题】:Best practices for Querying graphs by edge and node attributes in NetworkXNetworkX 中按边和节点属性查询图的最佳实践
【发布时间】:2013-03-16 16:44:56
【问题描述】:

使用 NetworkX 和库的新手,进行社交网络分析查询。通过查询,我的意思是通过两个边缘节点的属性选择/创建子图,其中边缘创建路径,节点包含属性。该图使用了 MultiDiGraph 的形式

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

查询

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" 

有没有更好的查询方式?还是创建自定义迭代来创建子图的最佳做法?

或者(和一个单独的问题),可以简化图表,但我没有使用下图,因为“讨厌”类型的对象会有前身。这会使查询更简单吗?似乎更容易遍历节点

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

其他说明:

  • 也许add_path 将标识符添加到创建的路径?
  • iGraph 有 一个nice query featureg.vs.select()

【问题讨论】:

    标签: python networkx igraph


    【解决方案1】:

    编写单行代码来创建具有特定属性的节点列表或生成器非常简单(此处显示的生成器)

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

    如果您的图表很大且固定,并且您想要进行快速查找,您可以像这样制作属性的“反向字典”,

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

    【讨论】:

    • 这些示例似乎提供了一种查找节点或边的好方法。但是要查找节点和边的组合?在您的示例中,想象一下查询。 “返回具有“Color=red”属性的边缘的鱼节点的子图。是否还有一条线来查询两者并搜索子图?例如,edges_iter 是否同时返回节点和边缘?
    • @JonathanHendler 我也在寻找这种风格的查询语言,它允许使用过滤器查询节点和边的组合,我认为它称为图形模式匹配语言,如 Cypher 或 ISO-GQL,但没有没有找到 networkx 的。
    【解决方案2】:

    @Aric's answer为基础,你可以找到这样的红鱼:

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

    【讨论】:

      【解决方案3】:

      为了根据边和节点的属性选择边,您可能希望使用图形 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)
      

      这将迭代过程抽象为select() 函数,您可以将查询编写为单独的、可测试的函数。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-03-18
        • 1970-01-01
        • 2021-08-02
        • 1970-01-01
        • 2013-12-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多