Python NetworkX 學習筆記


chapter1

快速開始

import networkx as nx
from matplotlib import pyplot as plt

G = nx.Graph() # create a graph object

G.add_node('A') # 一次添加一個節點(這里使用字母作為節點的id)
G.add_nodes_from(['B','C']) # 添加多個節點

G.add_edge('A','B') # 一次添加一條邊
G.add_edges_from([('B','C'),('A','C')]) # 一次添加多條
G.add_edges_from([('B', 'D'), ('C', 'E')])
plt.figure(figsize=(7.5,7.5)) # 7.5英寸*7.5英寸
nx.draw_networkx(G)
plt.show()

圖像的全局配置

plt.rcParams.update({
	'figure.figsize':(7.5,7.5)
})

chapter2

  • 學習目標
    • Graph:了解無向網絡的屬性以及它們如何使用NetworkX Graph類表示。
    • Attributes:如何將數據與節點和邊關聯。
    • Edge Weight:了解如何量化連接強度並為邊信息添加注釋。
    • DiGraph:了解有向網絡的屬性以及如何使用NetworkX DiGraph類表示。
    • MultiGraph and MultiDiGraph:了解擁有並行邊的網絡。

Graph類——無向網絡

import networkx as nx
from matplotlib import pyplot as plt

G = nx.karate_club_graph()
karate_pos = nx.spring_layout(G,k = 0.3) # 節點直接通過一條邊連接,將會靠的更近
plt.figure()
nx.draw_networkx(G,karate_pos)
plt.show()

Graph類提供了許多節點和邊進行交互的方法:

  • 獲取節點和邊的屬性的迭代器
list(G.nodes) # [0,1,2...]
list(G.edges) # [(0,1),(0,2)...]
  • 判斷節點或邊是否存在(根據id匹配)
hyh = 0
hyh in G # True
G.has_node(hyh) #True
member_id = 1
(hyh,member_id) in G.edges #True
G.has_edge(hyh,member_id) #True
  • 獲取節點的鄰居,通常,通過一條邊連接到某個特定節點的節點集稱為該節點的鄰居。
list(G.neighbors(hyh)) #[1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 13, 17, 19, 21, 31]

為節點和邊添加屬性

有時候,網絡節點和邊緣被附加了額外的信息。在Graph類中,每個節點和邊都可以有一組屬性來存儲這些附加信息。屬性可以簡單地作為存儲與節點和邊相關的信息的方便場所,也可以用於可視化和網絡算法。

Graph類允許您向節點添加任意數量的屬性。對於網絡G,每個節點的屬性都存儲在G處的dict中。節點[v],其中v是節點的ID。

  • 遍歷節點,添加club屬性
member_club = [
    0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
    0, 0, 0, 0, 1, 1, 0, 0, 1, 0,
    1, 0, 1, 1, 1, 1, 1, 1, 1, 1,
    1, 1, 1, 1]
for node_id in G.nodes:
    G.nodes[node_id]["club"] = member_club[node_id]
G.add_node(11, club=0)
  • 定制節點的顏色
node_color = [
    '#1f78b4' if G.nodes[v]["club"] == 0
    else '#33a02c' for v in G]
nx.draw_networkx(G, karate_pos, label=True, node_color=node_color)

  • 遍歷邊
# Iterate through all edges
for v, w in G.edges:
    # Compare `club` property of edge endpoints
    # Set edge `internal` property to True if they match
    if G.nodes[v]["club"] == G.nodes[w]["club"]: # 兩個節點直接存在聯系
        G.edges[v, w]["internal"] = True
    else:
        G.edges[v, w]["internal"] = False

internal = [e for e in G.edges if G.edges[e]["internal"]] # 存在聯系的數組
external = [e for e in G.edges if not G.edges[e]["internal"]]

# Draw nodes and node labels  多個線樣式,需要繪制多次
nx.draw_networkx_nodes(G, karate_pos, node_color=node_color)
nx.draw_networkx_labels(G, karate_pos)
# Draw internal edges as solid lines
nx.draw_networkx_edges(G, karate_pos, edgelist=internal)
# Draw external edges as dashed lines
nx.draw_networkx_edges(G, karate_pos, edgelist=external, style="dashed")# 虛線

為邊增加權重

定義計算邊權重的函數

def tie_strength(G, v, w):
    # Get neighbors of nodes v and w in G
    v_neighbors = set(G.neighbors(v))
    w_neighbors = set(G.neighbors(w))
    # Return size of the set intersection
    return 1 + len(v_neighbors & w_neighbors) # 交集大小

遍歷每條邊,計算權重

for v, w in G.edges: 
    G.edges[v, w]["weight"] = tie_strength(G, v, w)
# Store weights in a list
edge_weights = [G.edges[v, w]["weight"] for v, w in G.edges]

將邊權值傳遞給spring_layout(),將強連接的節點推的更近。

# 將邊權值傳遞給spring_layout(),將強連接節點推得更近
weighted_pos = nx.spring_layout(G, pos=karate_pos, k=0.3, weight="weight")

# Draw network with edge color determined by weight
nx.draw_networkx(
    G, weighted_pos, width=8, node_color=node_color,
    edge_color=edge_weights, edge_vmin=0, edge_vmax=6, edge_cmap=plt.cm.Blues)
# Draw solid/dashed lines on top of internal/external edges
nx.draw_networkx_edges(G, weighted_pos, edgelist=internal, edge_color="gray")
nx.draw_networkx_edges(G, weighted_pos, edgelist=external, edge_color="gray", style="dashed")

有向圖

這次從gxef中讀取數據,類型是directed有向圖,每條邊都包含source和target。

<?xml version='1.0' encoding='utf-8'?>
<gexf version="1.2" xmlns="http://www.gexf.net/1.2draft" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.w3.org/2001/XMLSchema-instance">
  <graph defaultedgetype="directed" mode="static" name="">
    <meta>
      <creator>NetworkX 2.2rc1.dev_20181126202121</creator>
      <lastmodified>26/11/2018</lastmodified>
    </meta>
    <nodes>
      <node id="0" label="0" />
      <node id="2" label="2" />
        	  <!-- 省略 -->
    </nodes>
    <edges>
      <edge id="0" source="0" target="2" />
      <edge id="1" source="0" target="5" />
	  <!-- 省略 -->
    </edges>
  </graph>
</gexf>

讀取文件中的數據,畫出圖形。

G = nx.read_gexf("data/knecht2008/klas12b-net-1.gexf",node_type=int)
student_pos = nx.spring_layout(G, k=1.5)
nx.draw_networkx(G, student_pos, arrowsize=20)

獲取節點鄰居,后繼,前驅。

list(G.neighbors(20))
list(G.successors(20))
list(G.predecessors(20))

有向圖轉化為無向圖

# Create undirected copies of G
G_either = G.to_undirected() # 默認情況下, 只要存在一個方向,就連接
G_both = G.to_undirected(reciprocal=True) # 兩個方向都存在的時候,才會創建
# Set up a figure
plt.figure(figsize=(10,5))
# Draw G_either on left
plt.subplot(1, 2, 1)
nx.draw_networkx(G_either, student_pos)
# Draw G_both on right
plt.subplot(1, 2, 2)
nx.draw_networkx(G_both, student_pos)

並行邊

例:A點到B點有許多條路

G = nx.MultiGraph()
G.add_edges_from([
    ("North Bank", "Kneiphof", {"bridge": "Krämerbrücke"}),
    ("North Bank", "Kneiphof", {"bridge": "Schmiedebrücke"}),
    ("North Bank", "Lomse",    {"bridge": "Holzbrücke"}),
    ("Lomse",      "Kneiphof", {"bridge": "Dombrücke"}),
    ("South Bank", "Kneiphof", {"bridge": "Grüne Brücke"}),
    ("South Bank", "Kneiphof", {"bridge": "Köttelbrücke"}),
    ("South Bank", "Lomse",    {"bridge": "Hohe Brücke"})
])

list(G.edges)[0] # ('North Bank', 'Kneiphof', 0)
G.edges['North Bank', 'Kneiphof', 0] # {'bridge': 'Krämerbrücke'}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM