python - 为节点分配多个属性

标签 python networkx

我想为我的节点分配一个属性。目前我正在使用以下数据示例创建一个网络:

Attribute   Source       Target Weight  Label
    87.5    Heisenberg   Pauli  66.3    1
    12.5    Beckham      Messi  38.1    0
    12.5    Beckham      Maradona 12    0
    43.5    water        melon  33.6    1

标签应给出节点的颜色(1=黄色,0=蓝色)。

网络代码:

 G = nx.from_pandas_edgelist(df, source='Source', target='Target', edge_attr='Weight') 

    collist = df.drop('Weight', axis=1).melt('Label').dropna() # I need this for the below lines of code because I want to draw nodes - their size - based on their degree

    degrees=[]
    for x in collist['value']:
        deg=G.degree[x]  
        degrees.append(100*deg)

    
    pos=nx.spring_layout(G)

    nx.draw_networkx_labels(G, pos, font_size=10)
    nx.draw_networkx_nodes(G, pos, nodelist=collist['value'], node_size = degrees, node_color=collist['Label'])
    nx.draw_networkx_edges(G, pos)

这段代码应该做的事情如下:节点的大小应该等于它们的度数(这解释了我的代码中的度数和collist)。边缘的厚度应等于Weight。应按以下链接分配(和更新)属性:( Changing attributes of nodes )。目前,我的代码不包含提到的链接中的分配,其中添加和更新如下:

G = nx.Graph()
G.add_node(0, weight=8)
G.add_node(1, weight=5)
G.add_node(2, weight=3)
G.add_node(3, weight=2)

nx.add_path(G, [2,5])
nx.add_path(G, [2,3])


labels = {
    n: str(n) + '\nweight=' + str(G.nodes[n]['weight']) if 'weight' in G.nodes[n] else str(n)
    for n in G.nodes
}

newWeights = \
    [
        sum( # summ for averaging
            [G.nodes[neighbor]['weight'] for neighbor in G.neighbors(node)] # weight of every neighbor
            + [G.nodes[i]['weight']] # adds the node itsself to the average
        ) / (len(list(G.neighbors(node)))+1) # average over number of neighbours+1
        if len(list(G.neighbors(node))) > 0 # if there are no neighbours
        else G.nodes[i]['weight'] # weight stays the same if no neighbours
    for i,node in enumerate(G.nodes) # do the above for every node
    ]
print(newWeights) 
for i, node in enumerate(G.nodes):
    G.nodes[i]['weight'] = newWeights[i] # writes new weights after it calculated them all.

请注意,我有超过 100 个节点,所以我无法手动执行此操作。 我尝试在代码中包含该属性,如下所示:

G = nx.from_pandas_edgelist(df_net, source='Source', target='Target', edge_attr=['Weight'])
    nx.set_node_attributes(G, pd.Series(nodes.Attribute, index=nodes.node).to_dict(), 'Attribute')

但是,我遇到了错误:

----> 1 network(df)

<ipython-input-72-f68985d20046> in network(dataset)
     24     degrees=[]
     25     for x in collist['value']:
---> 26         deg=G.degree[x]
     27         degrees.append(100*deg)
     28 

~/opt/anaconda3/lib/python3.8/site-packages/networkx/classes/reportviews.py in __getitem__(self, n)
    445     def __getitem__(self, n):
    446         weight = self._weight
--> 447         nbrs = self._succ[n]
    448         if weight is None:
    449             return len(nbrs) + (n in nbrs)

KeyError: 87.5

我希望得到的输出是一个网络,其中节点位于源列中,而它们的邻居位于目标列中。边缘的厚度取决于重量。标签给出源的颜色,而属性值应添加为标签并更新,如此链接上的问题/答案中所示:Changing attributes of nodes .

请参阅下面我正在尝试构建的网络类型的直观示例。图中的属性值是指更新前的值(newWeights),这也解释了为什么有些节点有缺失值。属性仅与源相关,其基于标签着色。边缘的厚度由重量给出。

enter image description here

最佳答案

import networkx as nx
import pandas as pd
import matplotlib.pyplot as plt

df = pd.DataFrame({"Attribute": [87.5, 12.5, 12.5, 43.5], "Source": ["Heisenberg", "Beckham", "Messi", "water"], "Target" : ["Pauli", "Messi", "Maradona", "melon"], "Weight" : [66.3, 38.1, 12, 33.6], "Label" : [1, 0, 0,1]})

G = nx.from_pandas_edgelist(df, source='Source', target='Target', edge_attr='Weight')

source_attrs = {df.Source[i]: {"Attribute": df.Attribute[i]} for i in range(len(df.Attribute))}

target_attrs = {df.Target[i]: {"Attribute": df.Attribute[i]} for i in range(len(df.Attribute))}



nx.set_node_attributes(G, source_attrs)
nx.set_node_attributes(G, target_attrs)

degrees=[100*G.degree[i] for i in G.nodes()]
weights = [G[u][v]['Weight']/10 for u,v in G.edges()]
colors = []
for node in G.nodes():
    if node in source_attrs.keys():
        colors.append('yellow')
    else:
        colors.append('blue')

pos=nx.spring_layout(G)

pos_attrs = {}
for node, coords in pos.items():
    pos_attrs[node] = (coords[0], coords[1] + 0.08)

labels = nx.get_node_attributes(G, "Attribute")

custom_node_attrs = {}
for node, attr in labels.items():
    custom_node_attrs[node] = str(node) + str(attr)

nx.draw_networkx_labels(G, pos_attrs, labels=custom_node_attrs, font_size=10)

nx.draw_networkx_nodes(G, pos, nodelist=G.nodes(), node_size = degrees, node_color=colors)

nx.draw_networkx_edges(G,pos, width=weights)

plt.show()


enter image description here

关于python - 为节点分配多个属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67275186/

相关文章:

python - 模块未找到错误 : No module named 'dnf' when running yum or dnf

python - Tkinter 滚动条不滚动

python - 基于节点颜色的圆形网络集群节点

python - 使用 matplotlib.pyplot 时如何显示节点标签?

python - 快速计算节点到节点集的距离

python - django.core.exceptions.ImproperlyConfigured : Could not resolve URL for hyperlinked relationship using view name "user-detail"

python - 4线程和12线程CPU之间没有明显的提升

python - 由于回复 pidboxes,Redis 在用作 Celery 代理时会占用大量内存

Python networkX MultiDiGraph 边数

python - 使用 Networkx 重叠社区检测