Python / NetworkX:按边缘出现频率将权重添加到边缘

发布于 2021-01-29 16:04:29

我创建了一个MultiDiGraph,在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

边缘: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())

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

此外,我能够使用以下方法缩放颜色:

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

在此处输入图片说明

关注者
0
被浏览
44
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    试试看它的大小。

    注意:我添加了一个现有边的副本,目的只是为了显示当多图中有重复时的行为。

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


知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看