2013-03-26 64 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()功能,您可以把你的查詢寫成單獨的可測試函數。

相關問題