繁体   English   中英

使用NetworkX记录有关属性的信息时,如何将有向图转换为无向图?

[英]How to transform directed graph to undirected graph while recording information about attributes using NetworkX?

我是NetworkX的新手,我认为有一个问题可能很笼统:如何获取定向网络,如何将其转换为非定向网络,并在此过程中记录有关原始定向网络中边缘的一些信息?

具体来说,我在NetworkX中有一个DiGraph,它记录了从id_from到id_to的链接。 每个边的属性是链接的月份和权重。

我想将此有向图转换为我记录为属性的无向图:

  • 每对(u,v)的总权重,即每个方向上边缘的权重之和,
  • 我第一次和最后一次看到这对(u,v)之间的链接,
  • 用于指示这是否是倒数/对角边的指示符,即布尔值,表示原始定向网络中是否同时存在两个边(u,v)和(v,u),
  • 边沿任一方向(即(u,v)和/或(v,u))存在的月数。

这是我开始的熊猫数据框示例:

In [12]: df
Out[12]: 
    id_from     id_to     total       month
0         a         b     100.0  2014-01-01
1         b         a      10.0  2014-02-01
2         a         c      15.0  2014-01-01
3         c         d       7.0  2015-06-01
4         d         c     500.0  2016-03-01

我将其作为DiGraph阅读:

In [13]: G = nx.from_pandas_dataframe(df, 'id_from', 'id_to', edge_attr = True, create_using = nx.DiGraph())
In [14]: print(G.edges(data = True))
Out[14]: [(a, b, {'id_from':  a, 'id_to': b, 'amount': 100.0, 'month': Timestamp('2014-01-01 00:00:00')}), (b, a, {'id_from':  b, 'id_to': a, 'amount': 10.0, 'month': Timestamp('2014-02-01 00:00:00')}), (a, c, {'id_from':  a, 'id_to': c, 'amount': 15.0, 'month': Timestamp('2014-01-01 00:00:00')}), (c, d, {'id_from':  c, 'id_to': d, 'amount': 7.0, 'month': Timestamp('2015-06-01 00:00:00')}), (d, c, {'id_from':  d, 'id_to': c, 'amount': 500.0, 'month': Timestamp('2016-03-01 00:00:00')})] 

然后,我最终希望获得一个图形,然后可以将其转换为熊猫数据框,如下所示:

     id_one  id_two  total  first_month  last_month  nr_months  bidirect
0         a       b  110.0   2014-01-01  2014-02-01        2.0       Yes
1         a       c   15.0   2014-02-01  2014-02-01        1.0        No
2         c       d  507.0   2015-06-01  2016-03-01        2.0       Yes

谁能帮我这个?

我似乎找不到类似的问题,但是如果我错了,请纠正我。 任何帮助深表感谢。

一种可能的方法是使用G.to_undirected()将有向图转换为无向图。 然后遍历边缘以更新每个边缘的所需属性,最后将图形转换为数据框:

import pandas as pd
import networkx as nx
import datetime

data = {
    'id_from': ['a', 'b', 'a', 'c', 'd'],
    'id_to': ['b', 'a', 'c', 'd', 'c'],
    'total': [100.0, 10.0, 15.0, 7.0, 500.0],
    'month': [datetime.datetime(2014, 1, 1), datetime.datetime(2014, 2, 1), datetime.datetime(2014, 1, 1), datetime.datetime(2015, 6, 1), datetime.datetime(2016, 3, 1)],
}
df = pd.DataFrame(data)
G = nx.from_pandas_edgelist(df, 'id_from', 'id_to', edge_attr=True, create_using=nx.DiGraph())

undirected = G.to_undirected()
for edge in undirected.edges(data=True):
    direction_1 = df.ix[(df['id_from'] == edge[0]) & (df['id_to'] == edge[1])]
    direction_2 = df.ix[(df['id_from'] == edge[1]) & (df['id_to'] == edge[0])]
    edges = pd.concat([direction_1, direction_2])
    edge[2]['bidirect'] = 'Yes' if (not direction_1.empty) & (not direction_2.empty) else 'No'
    edge[2]['total'] = edges['total'].sum()
    edge[2]['first_month'] = edges['month'].min()
    edge[2]['last_month'] = edges['month'].max()
    edge[2]['nr_months'] = edges['month'].nunique()
    del edge[2]['month']

print(nx.to_pandas_edgelist(undirected))

结果是:

  bidirect first_month last_month  nr_months source target  total
0       No  2014-01-01 2014-01-01          1      a      c   15.0
1      Yes  2014-01-01 2014-02-01          2      a      b  110.0
2      Yes  2015-06-01 2016-03-01          2      c      d  507.0

networkx图中的每个边缘本质上都是一个元组,其中前2个元素是边缘的节点,最后一个元素(edge [2])是具有边缘属性的字典。 因此,我们可以根据所需逻辑简单地更新此字典。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM