文件格式
邻接矩阵格式
使用csv保存邻接矩阵,示例格式如下:
注意:这里csv文件中是没有节点名称的
节点名称格式
使用txt单独保存节点名称,示例格式如下:
节点属性文件格式
这里用的是Excel存放节点属性
需要注意的是,Excel文件中只能存在一张表,否则程序会出错
创建有向网络
# -*- coding: UTF-8 -*-
# @Date :2024/5/13 11:32
# @Author :Kyle Cao
# @Software: PyCharm
# @Version : python 3.9.6; matplotlib 3.8.4; networkx 3.2.1
import pandas as pd
import networkx as nx
import matplotlib
matplotlib.use('TkAgg') # 需要指定一下,否则容易报错
import matplotlib.pyplot as plt
def creat_directed_network(adjacency_path, nodes_path):
# 读取邻接矩阵
df = pd.read_csv(adjacency_path, header=None, index_col=None) # 仅有邻接矩阵,没有节点名称
G = nx.from_pandas_adjacency(df, create_using=nx.DiGraph())
# 重新处理节点名称
node_name = [] # 实际上就是将节点名称按照顺序存放进列表中,可以不用进行文件操作,直接输入一个完整的列表
with open(nodes_path, mode='r', encoding='utf-8') as f:
for line in f:
if line.strip():
node_name.append(line.strip())
mapping = dict(zip(G, node_name))
G = nx.relabel_nodes(G, mapping)
return G
def get_nodes_attr_dic(G, node_attr_path):
df = pd.read_excel(node_attr_path, sheet_name=None, header=0, dtype=str) # 有表头
# 存在多张表
for k in df:
# print(k) # 每个sheet的名称
for item in df[k].values:
dic = {}
for key, val in zip(list(df[k].keys()), item.tolist()):
dic[key] = val
for key, val in dic.items():
G.nodes[dic['节点名称']][key] = val
return G
def deal_network(G):
"""
对社会网络分析的各种操作,可以在这个函数中进行
:param G:
:return:
"""
# 计算入度中心度
in_degree_centrality = nx.in_degree_centrality(G) # 入度中心度
# 计算出度中心度
out_degree_centrality = nx.out_degree_centrality(G) # 出度中心度
def draw_network(G):
"""
Networkx开发出了多种算法来计算每个节点的最佳位置。
fruchterman_reingold_layout:基于牛顿迭代法的布局算法
shell_layout:顶点在同心圆上分布
circular_layout:顶点在一个圆环上均匀分布
random_layout:顶点随机分布
spectral_layout:根据图的Laplace特征向量排列顶点
spring_layout:用Fruchterman-Reingold算法排列顶点
kamada_kawai_layout:基于牛顿迭代法的布局算法
planar_layout:基于欧拉回路的平面布局算法
:param G:
:return:
"""
# # 画图
# nx.draw(G, node_size=500, node_color='red', with_labels=True,font_family='SimSun') # font_family='SimSun' 如果是中文的话,需要指定字体
nx.draw_networkx(G, node_size=500, pos=nx.shell_layout(G), node_color='red', with_labels=True,
font_family='SimSun') # font_family='SimSun' 如果是中文的话,需要指定字体
plt.show()
def run(adjacency_path, nodes_path, node_attr_path):
G = creat_directed_network(adjacency_path, nodes_path) # 创建网络
# 更新节点属性
G = get_nodes_attr_dic(G, node_attr_path)
# 社会网络指标分析
deal_network(G) # 对网络进行各种处理
# 绘制社会网络图
draw_network(G)
if __name__ == '__main__':
adjacency_path = '处理后_邻接矩阵.csv' # 仅有邻接矩阵,没有节点名称
nodes_path = '节点名称.txt' # 节点名称单独保存,每一行是一个节点名称
node_attr_path = '事件属性.xlsx' # 节点属性名称,注意:Excel文件中只存放一个表
run(adjacency_path, nodes_path, node_attr_path)
代码可以直接运行,就不多赘述了。
后记
全网找了很久利用邻接矩阵文件创建有向图的完整代码,都比较零散,可用率不高,于是自己找了一些代码进行了汇总,整体代码是可用的,但因为我对这个networkx和pandas模块的了解不是特别深,就只能做到这一步了。