如何按日计算NetworkX图中指定节点的度中心性并优化代码
问题
我有一个涵盖数月事件的NetworkX图,想要查看特定节点的中心性分数随时间的变化。计划用多种中心性指标,所以写了个函数来筛选特定发送者和日期,构建NetworkX图并计算度中心性,结果存入DataFrame。但现在代码比较繁琐,而且输出里包含35、18这些无关节点,我只需要节点A的结果,想问问有没有更优的实现方式。
附上测试代码、当前输出及期望输出:
测试代码
import numpy as np import pandas as pd from datetime import datetime import networkx as nx df = pd.DataFrame({'feature':['A','B','A','B','A','B','A','B','A','B'], 'feature2':['18','78','35','14','57','68','57','17','18','78'], 'timestamp':['2017-01-20T11','2017-01-01T13', '2017-01-02T12','2017-02-01T13', '2017-03-01T14','2017-05-01T15', '2017-04-01T16','2017-04-01T17', '2017-12-01T17','2017-12-01T19']}) df['timestamp'] = pd.to_datetime(pd.Series(df['timestamp'])) df['date'], df['time']= df.timestamp.dt.date, df.timestamp.dt.time def test(feature,date,name,col_name,nx_measure): feature = df[df['feature']== feature] feature['date_str'] = feature['date'].astype(str) one_day = feature[feature['date_str']==date] oneDay_graph =nx.from_pandas_edgelist(one_day, source = 'feature', target = 'feature2', create_using=nx.DiGraph) name = pd.DataFrame() name['feature']= nx_measure(oneDay_graph).keys() name[col_name]= nx_measure(oneDay_graph).values() name['date'] = date return name a =test('A','2017-01-02','degree','degree',nx.degree_centrality) b = test('A','2017-01-20','degree','degree',nx.degree_centrality) a.append(b)
当前输出
feature degree date 0 A 1.0 2017-01-02 1 35 1.0 2017-01-02 0 A 1.0 2017-01-20 1 18 1.0 2017-01-20
期望输出
feature degree date 0 A 1.0 2017-01-02 0 A 1.0 2017-01-20
优化方案
可以从简化逻辑、精准过滤、批量处理三个角度优化代码,直接得到目标节点的结果:
改进后的代码
import numpy as np import pandas as pd import networkx as nx df = pd.DataFrame({'feature':['A','B','A','B','A','B','A','B','A','B'], 'feature2':['18','78','35','14','57','68','57','17','18','78'], 'timestamp':['2017-01-20T11','2017-01-01T13', '2017-01-02T12','2017-02-01T13', '2017-03-01T14','2017-05-01T15', '2017-04-01T16','2017-04-01T17', '2017-12-01T17','2017-12-01T19']}) df['timestamp'] = pd.to_datetime(df['timestamp']) df['date_str'] = df['timestamp'].dt.date.astype(str) # 提前统一处理日期格式,避免重复转换 def get_node_centrality(target_node, dates, col_name, nx_measure): # 提前筛选目标节点的所有数据,减少重复过滤 target_data = df[df['feature'] == target_node] result_rows = [] for date in dates: daily_data = target_data[target_data['date_str'] == date] if daily_data.empty: continue # 无数据时直接跳过 # 构建当日图并计算中心性(只算一次,避免重复调用) daily_graph = nx.from_pandas_edgelist(daily_data, source='feature', target='feature2', create_using=nx.DiGraph) centrality = nx_measure(daily_graph) # 只提取目标节点的结果,组装成字典 result_rows.append({ 'feature': target_node, col_name: centrality.get(target_node, 0.0), # 节点不存在时返回0.0作为默认值 'date': date }) return pd.DataFrame(result_rows) # 调用函数,传入目标节点和需要查询的日期列表 final_result = get_node_centrality('A', ['2017-01-02', '2017-01-20'], 'degree', nx.degree_centrality) print(final_result)
优化点说明
- 减少重复计算:原函数两次调用
nx_measure,现在只计算一次中心性分数,提升效率。 - 精准过滤结果:直接提取目标节点的分数,无需生成包含所有节点的DataFrame,彻底避免无关节点出现。
- 批量处理日期:支持传入日期列表,一次性处理多个日期,不用多次调用函数再拼接结果。
- 增加容错处理:判断当日是否有数据,避免空数据导致的报错。
运行后输出与期望完全一致:
feature degree date 0 A 1.0 2017-01-02 1 A 1.0 2017-01-20
内容的提问来源于stack exchange,提问作者Rebecca James
相关产品推荐
相关产品推荐

