如何创建有向图?

5 python networkx pandas

我试图在这个数据集上创建一个有向图:

    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
Run Code Online (Sandbox Code Playgroud)

为了用上面的数据创建一个无向图,我做了:

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) 
Run Code Online (Sandbox Code Playgroud)

我想在图中添加日期信息,以创建一个有向图:日期最早的ID是源。例如: Julie 和 Mirk 链接在一起:应该添加从 Julie 到 Mirk 的定向链接。

另一个例子:Chris 和 Mirk 彼此相连。但是,由于与 ID 相比,Chris 的日期最早,因此将 Mirk 与 Chris 联系起来。如果两个 ID 相互链接并且它们具有相同的日期,则它们应该有一个箭头(双向)。

我怎样才能弄清楚如何在我的图表中添加日期信息?

jla*_*rcy 4

根据您提供的数据(我添加了一条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)
Run Code Online (Sandbox Code Playgroud)

我们有以下数据集:

       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
Run Code Online (Sandbox Code Playgroud)

我们可以将数据框与其自身合并,以检查应保留哪种组合:

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'])
Run Code Online (Sandbox Code Playgroud)

假设您想保留最早的关系(例如:Chris -> Mirk而不是Mirk -> Chris),那么标准是:

c['keep'] = c['Date'] <= c['Date_r']
Run Code Online (Sandbox Code Playgroud)

如果您想要相反,只需将不等式关系更改为>=

结果如下:

      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
Run Code Online (Sandbox Code Playgroud)

构建有向图非常简单:

c = c.loc[c['keep'], :]
G = nx.from_pandas_edgelist(c, 'ID', 'Link_to', create_using=nx.DiGraph)
Run Code Online (Sandbox Code Playgroud)

最终结果大概是:

nx.draw_networkx(G)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

它似乎符合您的预期输出:

  • 表示单边;
  • 双边处理如下:
    • 日期相同,保留两边;
    • 日期不同,保留最早的日期。