Python案例如何用Networkx做图分析

wen python案例 2

本文目录导读:

Python案例如何用Networkx做图分析

  1. 基础安装和导入
  2. 创建不同类型的图
  3. 案例一:社交网络分析
  4. 案例二:交通网络最短路径
  5. 案例三:推荐系统(协同过滤)
  6. 案例四:网络传播模拟
  7. 高级分析功能
  8. 常用操作速查表

我来为你详细介绍使用 NetworkX 进行图分析的典型案例。

基础安装和导入

# 安装
# pip install networkx matplotlib
import networkx as nx
import matplotlib.pyplot as plt
import numpy as np

创建不同类型的图

# 创建无向图
G = nx.Graph()
# 创建有向图
DG = nx.DiGraph()
# 添加节点
G.add_nodes_from([1, 2, 3, 4, 5])
# 添加边
G.add_edges_from([(1, 2), (1, 3), (2, 3), (3, 4), (4, 5)])
# 添加带权重的边
G.add_edge(1, 2, weight=4.0)
G.add_edge(2, 3, weight=2.0)
# 可视化
nx.draw(G, with_labels=True, node_color='lightblue', 
        node_size=500, font_size=16)
plt.show()

案例一:社交网络分析

import networkx as nx
import matplotlib.pyplot as plt
# 创建社交网络
def create_social_network():
    G = nx.Graph()
    # 添加用户(节点)和关系(边)
    users = ['Alice', 'Bob', 'Charlie', 'David', 'Eve', 'Frank']
    G.add_nodes_from(users)
    # 添加朋友关系
    friendships = [
        ('Alice', 'Bob'), ('Alice', 'Charlie'), 
        ('Bob', 'Charlie'), ('Bob', 'David'),
        ('David', 'Eve'), ('Eve', 'Frank'),
        ('Charlie', 'Frank')
    ]
    G.add_edges_from(friendships)
    return G
# 分析社交网络
def analyze_social_network(G):
    print("=== 社交网络分析 ===")
    # 基本统计
    print(f"用户数量: {G.number_of_nodes()}")
    print(f"好友关系数量: {G.number_of_edges()}")
    # 计算度中心性(好友数量)
    degree_centrality = nx.degree_centrality(G)
    print("\n度中心性(影响力):")
    for user, centrality in sorted(degree_centrality.items(), 
                                    key=lambda x: x[1], reverse=True):
        print(f"{user}: {centrality:.3f}")
    # 找出最有人气的人
    most_popular = max(degree_centrality, key=degree_centrality.get)
    print(f"\n最受欢迎的人: {most_popular}")
    # 计算最短路径
    print("\n最短路径:")
    print(f"Alice到Frank: {nx.shortest_path(G, 'Alice', 'Frank')}")
    # 检测社区
    communities = nx.community.greedy_modularity_communities(G)
    print(f"\n检测到的社区数量: {len(communities)}")
    for i, community in enumerate(communities, 1):
        print(f"社区 {i}: {sorted(community)}")
    # 可视化
    plt.figure(figsize=(10, 8))
    pos = nx.spring_layout(G, seed=42)
    nx.draw(G, pos, with_labels=True, node_color='lightgreen',
            node_size=2000, font_size=10, font_weight='bold',
            edge_color='gray')
    plt.title("社交网络图")
    plt.show()
# 执行分析
G = create_social_network()
analyze_social_network(G)

案例二:交通网络最短路径

import networkx as nx
import matplotlib.pyplot as plt
# 创建交通网络
def create_transport_network():
    G = nx.Graph()
    # 添加城市节点和距离(权重)
    cities = ['北京', '上海', '广州', '深圳', '成都', '武汉', '西安']
    # 添加带权重的边(距离km)
    routes = [
        ('北京', '上海', 1200),
        ('北京', '西安', 1100),
        ('北京', '武汉', 1150),
        ('上海', '广州', 1400),
        ('上海', '深圳', 1300),
        ('广州', '深圳', 100),
        ('广州', '武汉', 850),
        ('武汉', '成都', 1100),
        ('西安', '成都', 700),
        ('成都', '深圳', 1500)
    ]
    G.add_weighted_edges_from(routes)
    return G
# 路径分析
def analyze_routes(G):
    print("=== 交通网络分析 ===")
    # 查找最短路径
    start, end = '北京', '深圳'
    shortest_path = nx.shortest_path(G, start, end, weight='weight')
    shortest_distance = nx.shortest_path_length(G, start, end, weight='weight')
    print(f"从{start}到{end}的最短路径:")
    print(f"路径: {' -> '.join(shortest_path)}")
    print(f"总距离: {shortest_distance}km")
    # 计算所有最短路径
    print(f"\n从{start}到所有城市的最短距离:")
    for city, distance in nx.single_source_dijkstra_path_length(G, start, weight='weight'):
        if city != start:
            print(f"{start} -> {city}: {distance}km")
    # 查找最小生成树(最经济的网络连接)
    mst = nx.minimum_spanning_tree(G, weight='weight')
    print(f"\n最小生成树总距离: {sum(weight for _, _, weight in mst.edges(data='weight'))}km")
    # 可视化
    plt.figure(figsize=(12, 8))
    pos = nx.spring_layout(G, seed=42)
    # 绘制原始网络
    nx.draw(G, pos, with_labels=True, node_color='lightblue',
            node_size=1500, font_size=12)
    # 添加边权重标签
    edge_labels = nx.get_edge_attributes(G, 'weight')
    nx.draw_networkx_edge_labels(G, pos, edge_labels=edge_labels)
    # 高亮最短路径
    path_edges = list(zip(shortest_path, shortest_path[1:]))
    nx.draw_networkx_edges(G, pos, edgelist=path_edges, 
                          edge_color='red', width=3)
    plt.title(f"交通网络 - 红色为{start}到{end}最短路径")
    plt.show()
# 执行分析
G = create_transport_network()
analyze_routes(G)

案例三:推荐系统(协同过滤)

import networkx as nx
import matplotlib.pyplot as plt
def create_recommendation_graph():
    G = nx.Graph()
    # 用户和商品
    users = ['User_A', 'User_B', 'User_C']
    products = ['商品1', '商品2', '商品3', '商品4', '商品5']
    # 用户-商品购买关系
    purchases = [
        ('User_A', '商品1'), ('User_A', '商品2'), ('User_A', '商品4'),
        ('User_B', '商品1'), ('User_B', '商品3'), ('User_B', '商品5'),
        ('User_C', '商品2'), ('User_C', '商品4'), ('User_C', '商品5')
    ]
    G.add_nodes_from(users, bipartite='users')
    G.add_nodes_from(products, bipartite='products')
    G.add_edges_from(purchases)
    return G, users, products
def generate_recommendations(G, users, products, target_user):
    print(f"\n=== 为{target_user}推荐商品 ===")
    # 找到目标用户购买的商品
    user_products = list(G.neighbors(target_user))
    print(f"{target_user}已购买: {user_products}")
    # 找到购买了相同商品的其他用户
    recommended_products = set()
    for product in user_products:
        similar_users = list(G.neighbors(product))
        for user in similar_users:
            if user != target_user:
                # 找出这些用户购买的其他商品
                other_products = list(G.neighbors(user))
                for p in other_products:
                    if p not in user_products:
                        recommended_products.add(p)
    print(f"推荐商品: {recommended_products}")
    return recommended_products
# 执行推荐
G, users, products = create_recommendation_graph()
recommendations = generate_recommendations(G, users, products, 'User_A')
# 可视化
plt.figure(figsize=(10, 6))
pos = nx.bipartite_layout(G, users)
nx.draw(G, pos, with_labels=True, node_color=['lightblue' if n in users else 'lightgreen' 
        for n in G.nodes()], node_size=1500)"用户-商品二分图")
plt.show()

案例四:网络传播模拟

import networkx as nx
import matplotlib.pyplot as plt
import random
def simulate_information_spread(G, start_node, probability=0.3, max_steps=5):
    """模拟信息传播"""
    infected = set([start_node])
    newly_infected = set([start_node])
    history = [list(infected)]
    for step in range(max_steps):
        next_infected = set()
        for node in newly_infected:
            # 对每个邻居以一定概率传播
            for neighbor in G.neighbors(node):
                if neighbor not in infected and random.random() < probability:
                    next_infected.add(neighbor)
        infected.update(next_infected)
        newly_infected = next_infected
        history.append(list(infected))
        if not newly_infected:
            break
    return infected, history
# 创建随机网络
G = nx.erdos_renyi_graph(20, 0.15, seed=42)
# 模拟信息传播
start_node = 0
infected, history = simulate_information_spread(G, start_node, probability=0.4)
print(f"传播前的节点数: {1}")
print(f"传播后的节点数: {len(infected)}")
print(f"传播率: {len(infected)/G.number_of_nodes()*100:.1f}%")
# 可视化传播过程
plt.figure(figsize=(8, 6))
pos = nx.spring_layout(G, seed=42)
colors = ['red' if n in infected else 'lightblue' for n in G.nodes()]
nx.draw(G, pos, with_labels=True, node_color=colors, 
        node_size=500, font_size=10)f"信息传播结果(从节点{start_node}开始)")
plt.show()

高级分析功能

import networkx as nx
def advanced_analysis(G):
    """高级图分析功能"""
    # 1. 中心性分析
    print("\n=== 中心性分析 ===")
    degree_cent = nx.degree_centrality(G)
    betweenness_cent = nx.betweenness_centrality(G)
    closeness_cent = nx.closeness_centrality(G)
    eigenvector_cent = nx.eigenvector_centrality(G)
    print(f"度中心性(前3名): {dict(sorted(degree_cent.items(), key=lambda x: x[1], reverse=True)[:3])}")
    print(f"介数中心性(前3名): {dict(sorted(betweenness_cent.items(), key=lambda x: x[1], reverse=True)[:3])}")
    # 2. 聚类系数
    print(f"\n全局聚类系数: {nx.average_clustering(G):.3f}")
    # 3. 密度
    print(f"网络密度: {nx.density(G):.3f}")
    # 4. 连通性分析
    if nx.is_connected(G):
        print("网络是连通的")
        print(f"直径: {nx.diameter(G)}")
        print(f"平均最短路径长度: {nx.average_shortest_path_length(G):.3f}")
    # 5. 检测桥接边(关键连接)
    bridges = list(nx.bridges(G))
    print(f"桥接边数量: {len(bridges)}")
    if bridges:
        print(f"桥接边: {bridges[:5]}...")  # 只显示前5个
# 创建示例图并分析
G = nx.karate_club_graph()  # 使用经典的Zachary's Karate Club数据集
advanced_analysis(G)
# 可视化
plt.figure(figsize=(10, 8))
pos = nx.spring_layout(G, seed=42)
nx.draw(G, pos, with_labels=True, node_color='lightcoral',
        node_size=500, font_size=8)"Zachary's Karate Club Network")
plt.show()

常用操作速查表

# 创建图
G = nx.Graph()           # 无向图
DG = nx.DiGraph()        # 有向图
# 添加节点/边
G.add_node(1)            # 添加单个节点
G.add_nodes_from([1,2,3]) # 添加多个节点
G.add_edge(1, 2)         # 添加单条边
G.add_edges_from([(1,2), (2,3)]) # 添加多条边
# 基本属性
G.number_of_nodes()      # 节点数
G.number_of_edges()      # 边数
G.nodes()                # 所有节点
G.edges()                # 所有边
G.degree()               # 度
# 路径分析
nx.shortest_path(G, 1, 3)        # 最短路径
nx.shortest_path_length(G, 1, 3) # 最短路径长度
nx.connected_components(G)       # 连通分量
# 中心性
nx.degree_centrality(G)          # 度中心性
nx.betweenness_centrality(G)     # 介数中心性
nx.closeness_centrality(G)       # 接近中心性

这些案例覆盖了 NetworkX 的主要功能,你可以根据实际需求调整和使用。

抱歉,评论功能暂时关闭!