2017-04-26 151 views
3

我在networkx中創建了一個MultiDiGraph,爲此我嘗試向邊緣添加權重,之後根據頻率/計數邊緣發生。我用下面的代碼來創建圖形,並添加砝碼,但我不知道如何根據計數處理重新分配權重:Python/NetworkX:通過邊緣發生的頻率向邊緣添加權重

g = nx.MultiDiGraph() 

df = pd.read_csv('G:\cluster_centroids.csv', delimiter=',') 
df['pos'] = list(zip(df.longitude,df.latitude)) 
dict_pos = dict(zip(df.cluster_label,df.pos)) 
#print dict_pos 


for row in csv.reader(open('G:\edges.csv', 'r')): 
    if '[' in row[1]:  # 
     g.add_edges_from(eval(row[1])) 

for u, v, d in g.edges(data=True): 
    d['weight'] = 1 
for u,v,d in g.edges(data=True): 
    print u,v,d 

編輯

我是能夠成功地分配權重每個邊緣,我原來的問題的第一部分,具有以下情況:

for u, v, d in g.edges(data=True): 
    d['weight'] = 1 
for u,v,d in g.edges(data=True): 
    print u,v,d 

然而,我仍然無法基於次的邊緣發生在我的圖中的單個邊緣,可能會發生多次的數目(重新分配權重)?我需要做到這一點,以便用更少的計數(使用邊緣顏色或寬度)可視化具有更高計數的邊。我不知道如何繼續重新分配基於計數的權重,請告知。以下是示例數據,以及指向我的完整數據集的鏈接。

數據

樣品質心(節點):

cluster_label,latitude,longitude 
0,39.18193382,-77.51885109 
1,39.18,-77.27 
2,39.17917928,-76.6688633 
3,39.1782,-77.2617 
4,39.1765,-77.1927 
5,39.1762375,-76.8675441 
6,39.17468,-76.8204499 
7,39.17457332,-77.2807235 
8,39.17406072,-77.274685 
9,39.1731621,-77.2716502 
10,39.17,-77.27 

樣品邊緣:

user_id,edges 
11011,"[[340, 269], [269, 340]]" 
80973,"[[398, 279]]" 
608473,"[[69, 28]]" 
2139671,"[[382, 27], [27, 285]]" 
3945641,"[[120, 422], [422, 217], [217, 340], [340, 340]]" 
5820642,"[[458, 442]]" 
6060732,"[[291, 431]]" 
6912362,"[[68, 27]]" 
7362602,"[[112, 269]]" 

完整數據

質心(節點):https://drive.google.com/open?id=0B1lvsCnLWydEdldYc3FQTmdQMmc

邊緣:​​

UPDATE

我能夠解決,至少是暫時的,過於不成比例邊緣寬度的問題,由於通過設置minLineWidth以及由乘以高邊權重重量:

minLineWidth = 0.25 

for u, v, d in g.edges(data=True): 
    d['weight'] = c[u, v]*minLineWidth 
edges,weights = zip(*nx.get_edge_attributes(g,'weight').items()) 

,並使用在nx.draw_networkx_edges()width=[d['weight'] for u,v, d in g.edges(data=True)]如在下面的溶液中提供。

此外,我能夠使用縮放顏色如下:

# Set Edge Color based on weight 
values = range(7958) #this is based on the number of edges in the graph, use print len(g.edges()) to determine this 
jet = cm = plt.get_cmap('YlOrRd') 
cNorm = colors.Normalize(vmin=0, vmax=values[-1]) 
scalarMap = cmx.ScalarMappable(norm=cNorm, cmap=jet) 
colorList = [] 

for i in range(7958): 
    colorVal = scalarMap.to_rgba(values[i]) 
    colorList.append(colorVal) 

,然後使用參數edge_color=colorListnx.draw_networkx_edges()

enter image description here

+0

請提供[MCVE]。我們沒有你的輸入文件,所以我們很難處理你的代碼。提取足夠的代碼來隔離問題。 –

+0

我道歉,我的意思是最初提供樣品。我提供了這兩個文件的示例以及指向Google雲端硬盤上完整數據的鏈接。 –

+0

假設節點A和節點B之間的邊在您的數據中出現3次。你是否想在節點之間有多個加權邊緣(即在A和B之間有3條邊,每條邊的權重爲3),還是你想要一條加權邊(即A和B之間的一條邊的權重爲3 )? – edo

回答

3

試試這個關於大小。

注意:我添加了現有邊的副本,只是爲了顯示多圖中有重複的行爲。

from collections import Counter 
c = Counter(g.edges()) # Contains frequencies of each directed edge. 

for u, v, d in g.edges(data=True): 
    d['weight'] = c[u, v] 

print(list(g.edges(data=True))) 
#[(340, 269, {'weight': 1}), 
# (340, 340, {'weight': 1}), 
# (269, 340, {'weight': 1}), 
# (398, 279, {'weight': 1}), 
# (69, 28, {'weight': 1}), 
# (382, 27, {'weight': 1}), 
# (27, 285, {'weight': 2}), 
# (27, 285, {'weight': 2}), 
# (120, 422, {'weight': 1}), 
# (422, 217, {'weight': 1}), 
# (217, 340, {'weight': 1}), 
# (458, 442, {'weight': 1}), 
# (291, 431, {'weight': 1}), 
# (68, 27, {'weight': 1}), 
# (112, 269, {'weight': 1})] 

編輯:爲了可視化與邊緣權重的圖形作爲厚度,使用:

nx.draw_networkx(g, width=[d['weight'] for _, _, d in g.edges(data=True)]) 
+0

工作,謝謝。作爲一個方面,我提到我正在嘗試使用重量來確定邊緣寬度或顏色,我如何使用您的解決方案來實現這一點?我嘗試使用這裏提供的解決方案http://stackoverflow.com/questions/17632151/coloring-networkx-edges-based-on-weight?rq=1和這裏http://stackoverflow.com/questions/22967086/colouring-edges重量在網絡x,但我沒有任何運氣剪裁你的解決方案。再次感謝! –

+0

更新了我的答案;應該解決你的問題。 –

+0

我收到一個值錯誤:'需要超過2個值才能解包' –