Python/NetworkX:按边出现的频率为边添加权重

Python/NetworkX: Add Weights to Edges by Frequency of Edge Occurance

我在 networkx 中创建了一个 MultiDiGraph,我试图为其边缘添加权重,之后我根据边缘出现的 frequency/count 分配一个新权重。我使用以下代码创建图表并添加权重,但我不确定如何处理基于计数的重新分配权重:

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

边缘:https://drive.google.com/open?id=0B1lvsCnLWydEdEtfM2E3eXViYkk

更新

通过设置 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)

然后在nx.draw_networkx_edges()中使用参数edge_color=colorList

试试这件尺码。

注意:我添加了一条现有边的副本,只是为了展示当您的多重图中存在重复时的行为。

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