计算节点子集的网络属性

时间:2021-01-06 17:41:02

标签: pandas networkx

上下文:我有两个表征网络的熊猫数据框,df_nodesdf_edges。它们可以通过共享标识符 id 进行匹配。

df_nodes 大致如下所示:

    id:     att_1:   att_2:  att_3:
    id1     red       ...    ...
    id2     red       ...    ...
    id3     blue      ...    ...

df_edges表征(加权)有向网络,但我现在对(加权)无向表示感兴趣。

   id_from: id_to:   weight:  
    id1     id2        0.5    .
    id1     id3        0.2      
    id2     id4        0.4

两个特点如下:

  • 同一节点有时出现在 id_from 列中,有时出现在 id_to 列中(在示例中,这将是 id_4;实际上有数百万条边) .

  • 更重要的是,df_edges 包括到 df_nodesnot 的节点的连接,即我没有这些节点的任何属性数据。

目标:我想创建一个 nx.Graph() 对象,该对象仅包含我具有属性数据的那些节点之间的边,即在 df_nodes 中的节点。然后,我想在 df_nodes 中添加(选定的)属性数据,并计算统计数据,例如具有某些属性值(例如 where {{1} }).

目前的方法:我是网络分析的新手,所以我所做的可能被误导了。 我首先创建 df_nodes[att_1]='red'

G

然后尝试添加感兴趣的属性

G = nx.from_pandas_edgelist(df_edges, 'id_from', 'id_to', 'weight', nx.Graph()) 

我想我可以使用类似下面的东西来过滤掉满足属性值的节点。

nx.set_node_attributes(G, df_nodes[['id','att_1',]].set_index('id').to_dict('index'),'id')

但是 (i) 这样做会引发一个关键错误,大概是因为许多节点甚至没有 nodes_subset = [x for x,y in G.nodes(data=True) if y['att_1']='red'] ,并且 (ii) 该方法似乎非常低效。

对于如何实现目标的任何帮助(考虑到实际数据的大小,并有效地实现),我将不胜感激!

1 个答案:

答案 0 :(得分:0)

我希望过滤 Pandas 数据帧比过滤 Networkx 图更快。所以我会尝试以下操作:

在属性表中创建节点字典:

nodes_with_attributes = {x:0 for x in df_nodes['id'].values}

(以内存为代价,在字典中查找比在列表中查找元素要快得多。)

然后过滤边缘:

df_filtered_edges = df_edges[
     (df_edges['id_from'].isin(nodes_with_attributes)& 
     (df_edges['id_to'].isin(nodes_with_attributes)]

然后您可以直接从过滤后的数据框中制作过滤后的图形。