如何创建有向图?
How to create a directed graph?
我正在尝试在此数据集上创建有向图:
ID Link_to Label Date Size
0 mary NaN 0 2020-01-23 1
1 Julie Mirk 1 2020-02-27 12
1 Julie Mark 1 2020-02-27 12
1 Julie Sarah 1 2020-02-27 12
1 Chris Mirk 1 2020-01-26 12
... ... ... ... ... ... ...
50 Mirk Chris 0 2020-04-29 4
51 Mark NaN 0 2020-04-29 3
52 Greg NaN 0 2020-04-27 2
53 Luke Matt 0 2020-04-08 1
54 Sarah James 0 2020-04-01 1
为了用我上面的数据创建一个无向图,我做了:
G = nx.from_pandas_edgelist(df, 'ID', 'Link_to')
d = dict(df.drop_duplicates(subset=['ID'])[['ID']]
.to_numpy().tolist())
nodes = G.nodes()
plt.figure(figsize=(20,33))
pos = nx.draw(G, with_labels=True,
nodelist=nodes,
node_color=[d.get(i,'lightgreen') for i in nodes],
node_size=1000)
我想在图中添加日期信息,以创建有向图:日期最早的ID是源。
例如:Julie 和 Mirk link 在一起:应该添加从 Julie 到 Mirk 的定向 link。
另一个例子:Chris 和 Mirk 相互关联。但是,由于与 ID 相比,Chris 的约会最早,因此无法将 Mirk 与 Chris 联系起来。如果两个 ID 相互 linked 并且它们具有相同的日期,则它们应该有一个箭头(双向)。
我如何知道如何在图表中添加日期信息?
所以我有一个你可以研究的理论
首先将日期转换为 Unix 时间戳,这是一个整数。
你可以看看下面的例子。
>>> import time
>>> import datetime
>>> s = "01/12/2011"
>>> time.mktime(datetime.datetime.strptime(s, "%d/%m/%Y").timetuple())
1322697600.0
现在,一旦您将整个列转换为 Unix 时间戳。你现在能做的只是简单的大于或小于('<', '>', '=')操作。换句话说,如果 A 的 unix 时间戳小于 B 的 Unix 时间戳,那么这意味着你有一条从 A 到 B 的有向边。
现在一旦你知道从 A 到 B 有一条有向边,你就可以使用
G.add_edge('A', 'B')
您可以查看有关定向图的更多信息here
根据您提供的数据(我添加了一个额外的行 Sarah -> Julie
与相同的 Date
):
s = """index ID Link_to Label Date Size
0 mary NaN 0 2020-01-23 1
1 Julie Mirk 1 2020-02-27 12
1 Julie Mark 1 2020-02-27 12
1 Julie Sarah 1 2020-02-27 12
1 Sarah Julie 1 2020-02-27 12
1 Chris Mirk 1 2020-01-26 12
50 Mirk Chris 0 2020-04-29 4
51 Mark NaN 0 2020-04-29 3
52 Greg NaN 0 2020-04-27 2
53 Luke Matt 0 2020-04-08 1
54 Sarah James 0 2020-04-01 1"""
df = pd.read_csv(io.StringIO(re.sub("[ ]+", ",", s)), parse_dates=['Date'])
df = df.dropna().drop(["index", "Label", "Size"], axis=1)
我们有以下数据集:
ID Link_to Date
1 Julie Mirk 2020-02-27
2 Julie Mark 2020-02-27
3 Julie Sarah 2020-02-27
4 Sarah Julie 2020-02-27
5 Chris Mirk 2020-01-26
6 Mirk Chris 2020-04-29
9 Luke Matt 2020-04-08
10 Sarah James 2020-04-01
我们可以将数据帧与自身合并以检查应该保留哪个组合:
c = df.merge(df, how='left', left_on=['ID', 'Link_to'], right_on=['Link_to', 'ID'], suffixes=('', '_r'))
c['Date_r'] = c['Date_r'].fillna(c['Date'])
假设你想保留最早的关系(例如:Chris -> Mirk
而不是 Mirk -> Chris
)那么标准是:
c['keep'] = c['Date'] <= c['Date_r']
如果您打算反过来,只需将不等式关系更改为>=
。
结果如下:
ID Link_to Date ID_r Link_to_r Date_r keep
0 Julie Mirk 2020-02-27 NaN NaN 2020-02-27 True
1 Julie Mark 2020-02-27 NaN NaN 2020-02-27 True
2 Julie Sarah 2020-02-27 Sarah Julie 2020-02-27 True
3 Sarah Julie 2020-02-27 Julie Sarah 2020-02-27 True
4 Chris Mirk 2020-01-26 Mirk Chris 2020-04-29 True
5 Mirk Chris 2020-04-29 Chris Mirk 2020-01-26 False
6 Luke Matt 2020-04-08 NaN NaN 2020-04-08 True
7 Sarah James 2020-04-01 NaN NaN 2020-04-01 True
构建有向图非常简单:
c = c.loc[c['keep'], :]
G = nx.from_pandas_edgelist(c, 'ID', 'Link_to', create_using=nx.DiGraph)
最终结果约为:
nx.draw_networkx(G)
它似乎符合您的预期输出:
- 单边表示;
- 双边缘处理如下:
- 相同的日期,保留两边;
- 不同的日期,保留最早的那个。
我正在尝试在此数据集上创建有向图:
ID Link_to Label Date Size
0 mary NaN 0 2020-01-23 1
1 Julie Mirk 1 2020-02-27 12
1 Julie Mark 1 2020-02-27 12
1 Julie Sarah 1 2020-02-27 12
1 Chris Mirk 1 2020-01-26 12
... ... ... ... ... ... ...
50 Mirk Chris 0 2020-04-29 4
51 Mark NaN 0 2020-04-29 3
52 Greg NaN 0 2020-04-27 2
53 Luke Matt 0 2020-04-08 1
54 Sarah James 0 2020-04-01 1
为了用我上面的数据创建一个无向图,我做了:
G = nx.from_pandas_edgelist(df, 'ID', 'Link_to')
d = dict(df.drop_duplicates(subset=['ID'])[['ID']]
.to_numpy().tolist())
nodes = G.nodes()
plt.figure(figsize=(20,33))
pos = nx.draw(G, with_labels=True,
nodelist=nodes,
node_color=[d.get(i,'lightgreen') for i in nodes],
node_size=1000)
我想在图中添加日期信息,以创建有向图:日期最早的ID是源。 例如:Julie 和 Mirk link 在一起:应该添加从 Julie 到 Mirk 的定向 link。
另一个例子:Chris 和 Mirk 相互关联。但是,由于与 ID 相比,Chris 的约会最早,因此无法将 Mirk 与 Chris 联系起来。如果两个 ID 相互 linked 并且它们具有相同的日期,则它们应该有一个箭头(双向)。
我如何知道如何在图表中添加日期信息?
所以我有一个你可以研究的理论 首先将日期转换为 Unix 时间戳,这是一个整数。 你可以看看下面的例子。
>>> import time
>>> import datetime
>>> s = "01/12/2011"
>>> time.mktime(datetime.datetime.strptime(s, "%d/%m/%Y").timetuple())
1322697600.0
现在,一旦您将整个列转换为 Unix 时间戳。你现在能做的只是简单的大于或小于('<', '>', '=')操作。换句话说,如果 A 的 unix 时间戳小于 B 的 Unix 时间戳,那么这意味着你有一条从 A 到 B 的有向边。
现在一旦你知道从 A 到 B 有一条有向边,你就可以使用
G.add_edge('A', 'B')
您可以查看有关定向图的更多信息here
根据您提供的数据(我添加了一个额外的行 Sarah -> Julie
与相同的 Date
):
s = """index ID Link_to Label Date Size
0 mary NaN 0 2020-01-23 1
1 Julie Mirk 1 2020-02-27 12
1 Julie Mark 1 2020-02-27 12
1 Julie Sarah 1 2020-02-27 12
1 Sarah Julie 1 2020-02-27 12
1 Chris Mirk 1 2020-01-26 12
50 Mirk Chris 0 2020-04-29 4
51 Mark NaN 0 2020-04-29 3
52 Greg NaN 0 2020-04-27 2
53 Luke Matt 0 2020-04-08 1
54 Sarah James 0 2020-04-01 1"""
df = pd.read_csv(io.StringIO(re.sub("[ ]+", ",", s)), parse_dates=['Date'])
df = df.dropna().drop(["index", "Label", "Size"], axis=1)
我们有以下数据集:
ID Link_to Date
1 Julie Mirk 2020-02-27
2 Julie Mark 2020-02-27
3 Julie Sarah 2020-02-27
4 Sarah Julie 2020-02-27
5 Chris Mirk 2020-01-26
6 Mirk Chris 2020-04-29
9 Luke Matt 2020-04-08
10 Sarah James 2020-04-01
我们可以将数据帧与自身合并以检查应该保留哪个组合:
c = df.merge(df, how='left', left_on=['ID', 'Link_to'], right_on=['Link_to', 'ID'], suffixes=('', '_r'))
c['Date_r'] = c['Date_r'].fillna(c['Date'])
假设你想保留最早的关系(例如:Chris -> Mirk
而不是 Mirk -> Chris
)那么标准是:
c['keep'] = c['Date'] <= c['Date_r']
如果您打算反过来,只需将不等式关系更改为>=
。
结果如下:
ID Link_to Date ID_r Link_to_r Date_r keep
0 Julie Mirk 2020-02-27 NaN NaN 2020-02-27 True
1 Julie Mark 2020-02-27 NaN NaN 2020-02-27 True
2 Julie Sarah 2020-02-27 Sarah Julie 2020-02-27 True
3 Sarah Julie 2020-02-27 Julie Sarah 2020-02-27 True
4 Chris Mirk 2020-01-26 Mirk Chris 2020-04-29 True
5 Mirk Chris 2020-04-29 Chris Mirk 2020-01-26 False
6 Luke Matt 2020-04-08 NaN NaN 2020-04-08 True
7 Sarah James 2020-04-01 NaN NaN 2020-04-01 True
构建有向图非常简单:
c = c.loc[c['keep'], :]
G = nx.from_pandas_edgelist(c, 'ID', 'Link_to', create_using=nx.DiGraph)
最终结果约为:
nx.draw_networkx(G)
它似乎符合您的预期输出:
- 单边表示;
- 双边缘处理如下:
- 相同的日期,保留两边;
- 不同的日期,保留最早的那个。