杰瑞科技汇

Networkx怎么用?基础操作指南?

这篇教程将从基础到进阶,涵盖 networkx 的核心用法。


目录

  1. 安装与导入
  2. 图的创建
    • 无向图
    • 有向图
    • 多重图
    • 创建图的几种方式
  3. 添加节点和边
    • 添加单个节点/边
    • 添加多个节点/边
    • 利用边属性
  4. 查询图信息
    • 节点和边
    • 节点数和边数
    • 节点和边的度
  5. 图的遍历
    • 深度优先遍历
    • 广度优先遍历
  6. 算法应用
    • 最短路径
    • 中心性
  7. 可视化
    • 使用 matplotlib 进行简单绘制
    • 可视化进阶技巧
  8. 实际应用案例:社交网络分析
  9. 总结与资源

安装与导入

你需要安装 networkx,如果还没有安装,请在终端或命令行中运行:

pip install networkx

安装完成后,在你的 Python 脚本或交互式环境中导入它:

import networkx as nx
import matplotlib.pyplot as plt # 通常用于可视化

图的创建

networkx 支持多种类型的图,最常见的三种是:

  • Graph: 无多重边(无平行边)的无向图。
  • DiGraph: 无多重边的有向图。
  • MultiGraph: 允许多重边的无向图。
  • MultiDiGraph: 允许多重边的有向图。

示例:创建一个无向图

# 创建一个空的、无向的图
G = nx.Graph()
# 创建一个包含节点的图
G_with_nodes = nx.Graph()
G_with_nodes.add_nodes_from([1, 2, 3, 4])
print(f"空图的节点: {list(G.nodes())}")
print(f"带初始节点的图: {list(G_with_nodes.nodes())}")

添加节点和边

这是构建图的核心操作。

添加单个节点/边

# 添加单个节点
G.add_node("A")
# 添加单个边
G.add_edge("A", "B")
# 添加一个不存在的节点时,会自动创建
G.add_edge("B", "C")

添加多个节点/边

使用列表或元组来批量添加。

# 添加多个节点
G.add_nodes_from(["D", "E", "F"])
# 添加多条边
G.add_edges_from([("A", "D"), ("B", "E"), ("C", "F")])

利用边属性

networkx 的一个强大功能是,边(和节点)可以附加属性,就像字典一样,这在表示带权重的图(如网络中的延迟、社交网络中的关系强度等)时非常有用。

# 添加带权重的边
G.add_edge("A", "E", weight=5.0)
G.add_edge("B", "C", weight=2.5, relationship="friend")
# 修改或添加边的属性
G["A"]["B"]["color"] = "blue"
print("边的属性:", G.edges(data=True))
# 输出: [('A', 'B', {'color': 'blue'}), ('A', 'E', {'weight': 5.0}), ...]

查询图信息

构建好图后,我们需要查询它的基本信息。

# 获取所有节点
print("所有节点:", list(G.nodes()))
# 获取所有边
print("所有边:", list(G.edges()))
# 获取节点数
print("节点数量:", G.number_of_nodes())
# 获取边数
print("边数量:", G.number_of_edges())
# 获取节点的度(与该节点相连的边的数量)
print("各节点的度:", dict(G.degree()))
# 获取带权重的度(边的权重之和)
print("各节点的加权度:", dict(G.degree(weight="weight")))

图的遍历

遍历图是许多算法的基础。

深度优先遍历

从起始节点开始,沿着一条路径走到底,然后回溯。

# 从节点 'A' 开始深度优先遍历
dfs_edges = list(nx.dfs_edges(G, source="A"))
print("深度优先遍历的边:", dfs_edges)
# 获取遍历的节点顺序
dfs_nodes = list(nx.dfs_preorder_nodes(G, source="A"))
print("深度优先遍历的节点顺序:", dfs_nodes)

广度优先遍历

从起始节点开始,先访问所有邻居,然后再访问邻居的邻居,像水波一样扩散。

# 从节点 'A' 开始广度优先遍历
bfs_edges = list(nx.bfs_edges(G, source="A"))
print("广度优先遍历的边:", bfs_edges)
# 获取遍历的节点顺序
bfs_nodes = list(nx.bfs_preorder_nodes(G, source="A"))
print("广度优先遍历的节点顺序:", bfs_nodes)

算法应用

networkx 内置了大量经典图论算法。

最短路径

# 创建一个带权重的图
G_weighted = nx.Graph()
G_weighted.add_edges_from([
    ("A", "B", {"weight": 4}),
    ("A", "C", {"weight": 2}),
    ("B", "C", {"weight": 1}),
    ("B", "D", {"weight": 5}),
    ("C", "D", {"weight": 8}),
    ("C", "E", {"weight": 10}),
    ("D", "E", {"weight": 2})
])
# 计算从 'A' 到 'E' 的最短路径(按边的权重和)
shortest_path = nx.shortest_path(G_weighted, source="A", target="E", weight="weight")
print("从 A 到 E 的最短路径:", shortest_path) # 输出: ['A', 'B', 'D', 'E']
# 计算最短路径的长度
shortest_path_length = nx.shortest_path_length(G_weighted, source="A", target="E", weight="weight")
print("最短路径的长度:", shortest_path_length) # 输出: 11

中心性

中心性用于衡量图中节点的重要性。

  • 度中心性: 连接数最多的节点最重要。
  • 接近中心性: 到所有其他节点平均距离最短的节点最重要。
  • 介数中心性: 在最多节点对之间的最短路径上出现的节点最重要。
# 度中心性
degree_centrality = nx.degree_centrality(G_weighted)
print("度中心性:", degree_centrality)
# 接近中心性
closeness_centrality = nx.closeness_centrality(G_weighted)
print("接近中心性:", closeness_centrality)
# 介数中心性
betweenness_centrality = nx.betweenness_centrality(G_weighted)
print("介数中心性:", betweenness_centrality)

可视化

使用 matplotlib 可以轻松地将图可视化。

使用 matplotlib 进行简单绘制

# 创建一个随机图用于演示
G_random = nx.erdos_renyi_graph(20, 0.1) # 20个节点,连接概率为0.1
# 设置绘图布局
pos = nx.spring_layout(G_random) # 一种常用的力导向布局
# 绘制节点
nx.draw_networkx_nodes(G_random, pos, node_size=500)
# 绘制边
nx.draw_networkx_edges(G_random, pos, alpha=0.5)
# 绘制节点标签
nx.draw_networkx_labels(G_random, pos)
# 显示图形"随机图可视化")
plt.show()

可视化进阶技巧

你可以根据节点的度或边的属性来调整可视化效果。

# 创建一个带权重的图
G_vis = nx.Graph()
G_vis.add_edges_from([
    ("A", "B", {"weight": 8}),
    ("A", "C", {"weight": 2}),
    ("B", "C", {"weight": 1}),
    ("B", "D", {"weight": 5}),
    ("C", "D", {"weight": 3}),
])
# 使用不同的布局
pos = nx.circular_layout(G_vis)
# 获取节点的度,用于设置节点大小
node_sizes = [300 * G_vis.degree(node) for node in G_vis.nodes()]
# 获取边的权重,用于设置边的宽度
edge_widths = [G_vis[u][v]['weight'] for u, v in G_vis.edges()]
# 绘制图形
plt.figure(figsize=(8, 8))
nx.draw_networkx_nodes(G_vis, pos, node_size=node_sizes, node_color='skyblue')
nx.draw_networkx_edges(G_vis, pos, width=edge_widths, alpha=0.7, edge_color='gray')
nx.draw_networkx_labels(G_vis, pos, font_size=12, font_family='sans-serif')
# 添加边权重标签
edge_labels = nx.get_edge_attributes(G_vis, 'weight')
nx.draw_networkx_edge_labels(G_vis, pos, edge_labels=edge_labels)
"带权重和大小调整的图")
plt.axis('off') # 关闭坐标轴
plt.show()

实际应用案例:社交网络分析

假设我们有一个简单的社交网络,表示谁是谁的朋友。

# 创建一个社交网络图
social_network = nx.Graph()
# 添加人(节点)
people = ["Alice", "Bob", "Charlie", "David", "Eve"]
social_network.add_nodes_from(people)
# 添加朋友关系(边)
friendships = [("Alice", "Bob"), ("Alice", "Charlie"), ("Bob", "David"), ("Charlie", "David"), ("David", "Eve")]
social_network.add_edges_from(friendships)
# 分析:谁是社交中心?
degree_centrality = nx.degree_centrality(social_network)
print("社交中心性(谁的朋友最多):")
for person, centrality in sorted(degree_centrality.items(), key=lambda item: item[1], reverse=True):
    print(f"{person}: {centrality:.2f}")
# 分析:谁连接了不同的朋友圈?
# 我们可以给边添加属性,"since" (认识年份)
nx.set_edge_attributes(social_network, {("Alice", "Bob"): 2025, ("Alice", "Charlie"): 2025, ("Bob", "David"): 2025, ("Charlie", "David"): 2025, ("David", "Eve"): 2025}, "since")
# 可视化社交网络
pos = nx.spring_layout(social_network, seed=42) # seed使布局每次都一样
nx.draw(social_network, pos, with_labels=True, node_color='lightgreen', node_size=1500, font_size=10)"简单社交网络")
plt.show()

总结与资源

networkx 是一个非常灵活和强大的库,是进行图论分析和网络科学研究的利器。

核心要点回顾:

  1. 创建图: nx.Graph(), nx.DiGraph()
  2. 添加元素: add_node(s), add_edge(s),并可以为它们添加属性。
  3. 查询信息: nodes(), edges(), degree(), number_of_nodes()
  4. 遍历: nx.dfs_edges(), nx.bfs_edges()
  5. 算法: nx.shortest_path(), nx.degree_centrality() 等。
  6. 可视化: 结合 matplotlib 进行绘制,可以自定义节点大小、颜色、边宽度和标签。

进一步学习的资源:

  • 官方文档: NetworkX Documentation (这是最好的资源,包含所有函数、类和教程)
  • NetworkX 示例: NetworkX Gallery (有大量可运行的代码示例)
  • 相关库:
    • igraph: 一个更快的图论库,有 Python、R、C接口。
    • graph-tool: 一个基于 C++ 的、高性能的 Python 图库。
    • pyvis: 一个专注于交互式 Web 可视化的库。

希望这份详细的教程能帮助你快速上手 networkx

分享:
扫描分享到社交APP
上一篇
下一篇