Python / NetworkX:即时计算边缘权重 [英] Python/NetworkX: calculate edge weights on the fly

查看:1476
本文介绍了Python / NetworkX:即时计算边缘权重的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个用 networkx 创建的未加权图,我想根据计数/频率计算节点之间的边的权重边缘发生。我的图形中的边缘可能会出现多次,但边缘外观的频率并未事先知晓。目的是基于连接节点之间的移动的权重(例如计数/频率)来可视化边缘。本质上,我想创建一个连接节点之间移动的网络流量图,并基于颜色或边缘宽度进行可视化。例如,从节点0到1的边缘在它们之间有10次移动,节点1到2有5次,所以边缘0-1将使用不同的边缘颜色/尺寸进行可视化。

我该如何计算两个节点之间的边的权重(将它们添加到图中后用 g.add_edges_from()),然后重新应用到我的图形可视化?以下是我最初创建图形所用的图形,数据和代码示例,以及我尝试失败的解决方案。




$ b

示例数据

群集质心(节点)

  cluster_label,纬度,经度
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,轨迹
11011.0, [[340,269],[269,340]]
80973.0,[[398,279]]
608473.0[[69,28]]
2139671.0, [$ 382,​​27],[27,285]]
3945641.0,[[120,422],[422,217],[217,340],[340,340]]
5820642.0,[[458,442]]
6060732.0[[291,431]]
6912362.0​​,[[68,27]]
7362602.0,[[112,269]]
8488782.0 ,[[133,340],[340,340]]

/ strong>

  import csv 
将networkx导入为nx
将pandas导入为pd
导入社区
import matplotlib.pyplot as plt
import time
import mplleaflet
$ bg = nx.MultiGraph()

df = pd.read_csv ('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('edges.csv','r')):
if'['在行[1]中:#
g.add_edges_from(eval(row [1]))

#使用mplleaflet绘图
fig,ax = plt.subplots()
nx.draw_networkx_nodes(g,pos = dict_pos,linewidths = 0.01,edge_color ='k',alpha = .05(g,pos = dict_pos,node_size = 50,node_color ='b')
nx.draw_networkx_edges )
nx.draw_networkx_labels(g,dict_pos)
mplleaflet.show(fig = ax.figure)

我尝试过使用 g.add_weighted_edges_from()并添加 weight = 1 作为属性,但没有任何运气。我也尝试过使用这种方法,但也没有奏效:

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


解决方案

未回答,关于此主题的第二个问题已打开(此处: Python / NetworkX:通过边界发生的频率向边缘添加权重)。

  g = nx.MultiDiGraph()
$ b $添加边的权重b 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 csv.reader(open('G:\edges (行[1]))

如果行[1]中有'[''):
g.add_edges_from u,v,d in g.edges(data = True):
d ['weight'] = 1
for u,v,d in g.edges(data = True):
打印u,v,d

根据以上计数缩放颜色和边缘宽度:

  minLineWidth = 0.25 

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

values = range(len(g.edges())
jet = cm = plt.get_cmap('Y10 rRd')
cNorm = colors.Normalize(vmin = 0,vmax = values [-1])$ ​​b $ b scalarMap = cmx.ScalarMappable(norm = cNorm,cmap = jet)
colorList = [ ]

(len(g.edges())):
colorVal = scalarMap.to_rgba(values [i])
colorList.append(colorVal)

并传递 width = [d ['weight'] for u,v,d在 nx.draw_networkx_edges()中使用g.edges(data = True)] edge_color = colorList code>


I have an unweighted graph created with networkx for which I would like to calculate the weight of edges between nodes based on the count/frequency of an edge occurrence. An edge in my graph can occur more than once but the frequency of an edge appearance is not known in advance. The purpose is to visualize the edges based on the weight (e.g. count/frequency) of moves between connected nodes. Essentially, I'd like to create a network traffic map of movement between connected nodes, and visualize based on color or edge width. E.g., edge from node 0 to 1 has 10 movements between them, and node 1 to 2 has 5, so edge 0-1 would be visualized using a different edge color/size.

How can I calculate the weight of edges between two nodes, on the fly (after adding them to the graph with g.add_edges_from()), and then reapply to my graph for visualization? Below is a sample of my graph, data, and code I've used to create the graph initially and a solution I attempted that failed.

Graph

Sample Data

Cluster centroids(nodes)

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

Trajectories(edges)

user_id,trajectory
11011.0,"[[340, 269], [269, 340]]"
80973.0,"[[398, 279]]"
608473.0,"[[69, 28]]"
2139671.0,"[[382, 27], [27, 285]]"
3945641.0,"[[120, 422], [422, 217], [217, 340], [340, 340]]"
5820642.0,"[[458, 442]]"
6060732.0,"[[291, 431]]"
6912362.0,"[[68, 27]]"
7362602.0,"[[112, 269]]"
8488782.0,"[[133, 340], [340, 340]]"

Code

import csv
import networkx as nx
import pandas as pd
import community
import matplotlib.pyplot as plt
import time
import mplleaflet

g = nx.MultiGraph()

df = pd.read_csv('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('edges.csv', 'r')):
    if '[' in row[1]:       #
        g.add_edges_from(eval(row[1]))

# Plotting with mplleaflet
fig, ax = plt.subplots()
nx.draw_networkx_nodes(g,pos=dict_pos,node_size=50,node_color='b')
nx.draw_networkx_edges(g,pos=dict_pos,linewidths=0.01,edge_color='k', alpha=.05)
nx.draw_networkx_labels(g,dict_pos)
mplleaflet.show(fig=ax.figure)

I have tried using g.add_weighted_edges_from() and adding weight=1 as an attribute, but have not had any luck. I also tried using this which also did not work:

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

解决方案

Since this went unanswered, a 2nd question on this topic was opened (here: Python/NetworkX: Add Weights to Edges by Frequency of Edge Occurance) which received responses. To add weights to edges based on count of edge occurrence:

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

To scale color and edge width based on the above count:

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

values = range(len(g.edges()) 
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(len(g.edges()):
    colorVal = scalarMap.to_rgba(values[i])
    colorList.append(colorVal)

and passing width=[d['weight'] for u,v, d in g.edges(data=True)], edge_color=colorList as arguments in nx.draw_networkx_edges()

这篇关于Python / NetworkX:即时计算边缘权重的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆