2013-03-26 83 views
18

对社交网络分析查询使用NetworkX和库新增功能。通过查询,我的意思是通过边缘创建路径的两个边缘节点的属性来选择/创建子图,并且节点包含属性。该图是使用与通过NetworkX中边缘和节点属性查询图形的最佳实践

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" 

查询的形式

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

的MultiDiGraph是否有更好的方法来查询?或者是创建自定义迭代来创建子图的最佳实践?

或者(和一个单独的问题),该图可以简化,但我没有使用下面的图,因为“恨”类型的对象将具有预处理器。这会使查询更简单吗?似乎更容易在节点迭代

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

回答

8

大厦@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]) 
21

这是非常简单的写一行代码,使各节点列表或生成具有特定属性(如图所示发电机)

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 
+0

的例子似乎提供了查找任何节点或边缘的好办法。但要查找节点和边的组合?在你的例子中想象这个查询。 “返回同样具有边的属性为”Color = red“的鱼类节点的子图。是否还有一个用于查询两者的单线程并搜索子图?例如,edges_iter是否返回节点和边? – 2013-03-27 04:35:54

7

为了选择基于边沿和节点属性的边缘,你可能想要做这样的事情,用你的图,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()功能,您可以把你的查询写成单独的可测试函数。