Python 用Networkx创建一个图

1. 数据预处理

# 读取CSV文件
import pandas as pd
import matplotlib.pyplot as plt

E13_users = pd.read_csv('users.csv')
# E13_users = E13_users[1:200]
E13_followers = pd.read_csv('followers.csv',header=1,names=["follower", "friend"])
E13_friends = pd.read_csv('friends.csv',header=1,names=["friend","follower"])

# 筛选网络中的连边
In_net_followers = E13_followers[E13_followers["follower"].isin(E13_users["id"])]
In_net_friends = E13_friends[E13_friends["friend"].isin(E13_users["id"])]
In_net_followers.to_csv("follow_edge.csv")
In_net_friends.to_csv("friend_edge.csv")

对于pandas dataframe,可以用.isin函数判断一个数据是否在另一个数据框中。直接将布尔值列表放在索引框中即可实现筛选。

2. 创建有向图

import networkx as nx

def build_Graph():
    G = nx.DiGraph()
    # 遍历用户id
    for user_id in E13_users["id"]:
        # 若此结点尚不存在,添加用户结点
        if not user_id in G.nodes:
            G.add_node(user_id, id=user_id)
        try:
            followers = In_net_followers[In_net_followers["friend"] == user_id]
            friends = In_net_friends[In_net_friends["follower"] == user_id]
            for follower in followers["follower"]:
                if not follower in G.nodes:
                    G.add_node(follower, id = follower)
                    # 添加连边
                G.add_edge(follower, user_id)
            for friend in friends["friend"]:
                if not friend in G.nodes:
                    G.add_node(friend, id = friend)
                # 添加连边
                G.add_edge(user_id, friend)
        except(ValueError, IOError):
            print(user_id)
            pass
    return G

G = build_Graph()

可以用如下代码查看图的节点数、边数等基本信息

print(G)
print(G.nodes)
print(G.edges)

其它图级别基本操作

# 判断是否是有向图
print(G.is_directed())

# 添加图级别属性
G.graph["name"]="Bar"
print(G.graph)

# 获取结点属性、边属性
node_attr = G.nodes[a]
edge_attr = G.edges[(a,b)]
print("Node a has the attribute {}".format(node_attr))

# 图中所有结点信息
G.nodes(data=True)

# 获取图中结点、边的数量
num_nodes = G.number_of_nodes()
num_edges = G.number_of_edges()

3. 计算图中各结点的中心性、度、聚类系数,随机分配位置

import scipy
# 使用pagerank函数需要引入scipy包
pagerank_c_degree = nx.pagerank(G, alpha=0.9)
# 度中心度(Degree Centrality)
degree_centrality = nx.degree_centrality(G)
# 接近度中心度(“Closeness Centrality”)
closeness_centrality = nx.closeness_centrality(G)
# 中间中心度(“Betweenness Centrality”)
betweenness_centrality = nx.betweenness_centrality(G)
# 特征向量中心度(“Eigenvector Centrality”)
eigenvector_centrality = nx.eigenvector_centrality(G)


# 给节点随机分配一些位置坐标,计算结点的度,中心度,聚类系数
pos = nx.shell_layout(G)
degree = nx.degree(G)
cluster = nx.clustering(G)
centrality = eigenvector_centrality.values()

# 将以上属性加入到图中
nx.set_node_attributes(G, pos, "pos")
nx.set_node_attributes(G, degree, "degree")
nx.set_node_attributes(G, cluster, "cluster")
nx.set_node_attributes(G, centrality, "centrality")

关于聚类系数的说明:

聚类系数衡量了一个节点的邻居之间的连接紧密程度,它是一个介于 0 和 1 之间的值。聚类系数越接近 1,表示节点的邻居之间越紧密地相互连接,而聚类系数接近 0 则表示节点的邻居之间连接不太紧密。

4. 绘制中心性分布直方图

# 绘制以上属性的分布直方图
def hist_plot(list,title="Centrality Distribution",xlabel="Centrality Value",ylabel="Frequency"):
    plt.hist(list, bins = 20, edgecolor='black', alpha=0.7)
    plt.title(title)
    plt.xlabel(xlabel)
    plt.ylabel(ylabel)
    plt.show()


hist_plot(list(dict(eigenvector_centrality).values()),title="Centrality Distribution", xlabel="Centrality")
hist_plot(list(dict(degree).values()),title="Degree Distribution", xlabel="Degree")
hist_plot(list(dict(cluster).values()),title="Local Clustering coefficient Distribution", xlabel="Clustering coefficient")

5. 绘制度数-聚类系数散点图

# 绘制度数-聚类系数散点图
def scatter_plot(x,y):
    plt.scatter(x,y, alpha=0.7)
    plt.title("Degree vs Clustering Coefficient")
    plt.xlabel("Degree")
    plt.ylabel("Clustering Coefficient")
    plt.show()
scatter_plot(list(dict(degree).values()),list(dict(cluster).values()))

6. 图可视化

# 图可视化
plt.figure(figsize=(10,10))
nx.draw_networkx_edges(G, pos, alpha=0.4)
nx.draw_networkx_nodes(
    G,
    pos,
    node_size=10,
    node_color=list(color.values())
)

plt.xlim(-2,2)
plt.ylim(-2,2)
plt.axis("off")
plt.show()

draw_networkx_edges参数表

G:一个networkx图

pos:dictionary,将节点作为键和位置作为值的字典。应该是长度为2的序列。

edgelist:边元组的集合,可以选择只绘制指定的边(默认= G.edges())

width:float或float数组,表示边线宽度(默认值= 1.0)

edge_color:颜色字符串或浮点数组,边颜色。可以是单颜色格式字符串(default ='r'),或者具有与edgelist相同长度的颜色序列。

style:string,边线样式(默认='solid')(实线|虚线|点线,dashdot)

alpha:float,边透明度(默认值= 1.0)

arrows:bool,optional(default = True),对于有向图,如果为真,则绘制箭头。

label:图例的标签

draw_networkx_nodes参数表

G:一个networkx图

pos:dictionary,将节点作为键和位置作为值的字典。应该是长度为2的序列。

nodelist:边元组的集合,可以选择只绘制指定的结点(默认= G.nodes())

node_size:标量或数组,节点大小(默认值= 300)。如果指定了数组,它必须是与点列表长度相同。

edge_color:颜色字符串或浮点数组,结点颜色。可以是单颜色格式字符串(default ='r'),或者具有与nodelist相同长度的颜色序列。

node_shape:string 节点的形状。规格为matplotlib.scatter 标记,'so ^> v

alpha:float,边透明度(默认值= 1.0)

arrows:bool,optional(default = True),对于有向图,如果为真,则绘制箭头。

label:图例的标签

图可视化的更多说明:

NetworkX — NetworkX documentation

可以参考的链接
 

DegreeView不是字典,是(节点,度数)对的迭代器。

如果不关心顺序的话,可以使用以下代码将其转换为字典

import networkx as nx
import matplotlib.pyplot as plt

G = nx.Graph()
G.add_edges_from([['9606.EN01','9606.EN02'],['9606.EN01','9606.EN03']])

my_degrees = G.degree();
degree_values = dict(my_degrees).values()

你可能感兴趣的:(python,开发语言)