获取不同节点组的 NetworkX 二维位置作为附加 Pandas DataFrame 列
Get NetworkX 2D position of different group of nodes as an additional Pandas DataFrame column
我有一个 DataFrame 构造为边缘列表和多个子节点和边缘元数据列,大约有 10 000 个条目。
Child | Parent | ChildCategory | ChildDescription | EdgeType | Root |
C1 'root' X Lorem Ipsum Strong C1
C2 C1 X Lorem Ipsum Strong C1
C3 C2 Y Lorem Ipsum Strong C1
C4 C2 Y Lorem Ipsum Strong C1
C5 'root' X Lorem Ipsum Strong C5
C6 C5 X Lorem Ipsum Strong C5
C7 C6 Y Lorem Ipsum Weak C5
... ... ... ... .. ..
我可以使用 networkx 将数据帧转换为图形。
G = nx.from_pandas_edgelist(df,source="Parent",target= "Child",edge_attr=["EdgeType"],create_using = nx.MultiDiGraph())
node_meta_data = ["ChildCategory","ChildDescription","Root"]
for col in node_meta_data:
nx.set_node_attributes(G,dict(zip(node_list_df,df[col].fillna('').tolist())),col)
我现在想做的是获取每组 Root
列的每个节点的二维位置,并将其返回到 DataFrame 列,以便我可以在另一个程序中可视化节点。
如果我要在整个图上做,我可以这样做。
df = pd.DataFrame(index=G.nodes())
for col in node_meta_data:
df[col] = pd.Series(nx.get_node_attributes(G, col))
df['EdgeType'] = nx.get_edge_attributes(G,'EdgeType')
### Here is the problem.
df['position'] = pd.Series(nx.kamada_kawai_layout(G))) ##Without group by root.
#### But I need position per group of root.
....
但是我将如何针对每个根组执行此操作,是否可以以智能方式将 pandas group_by
与 G.subgraph()
一起使用?
编辑:位置列应反映子列的位置。
您似乎想要从每个 root
节点开始的不同子图。为此,您需要更改每个 root
节点的名称,因为必须区分它们。一种方式可能是:
is_root = df.Parent.eq("'root'")
df.loc[is_root, 'Parent'] += is_root.cumsum().astype(str)
这将给出:
print(node_list_df)
Child Parent ChildCategory ChildDescription EdgeType Root
0 C1 'root'1 X LoremIpsum Strong C1
1 C2 C1 X LoremIpsum Strong C1
2 C3 C2 Y LoremIpsum Strong C1
3 C4 C2 Y LoremIpsum Strong C1
4 C5 'root'2 X LoremIpsum Strong C5
5 C6 C5 X LoremIpsum Strong C5
6 C7 C6 Y LoremIpsum Weak C5
现在,如果我们从修改后的数据框构建图,我们现在会得到两个不同的子图,对于来自每个 root
节点的后继者:
G = nx.from_pandas_edgelist(node_list_df,source="Parent",
target= "Child",
create_using = nx.DiGraph())
pos = nx.kamada_kawai_layout(G)
nx.draw(G, pos=pos,
node_color='lightblue',
with_labels=True,
node_size=500)
我们现在可以使用布局中的位置更新数据框:
pos = (pd.DataFrame(pos, index=['x', 'y']).T
.rename_axis('Parent')
.reset_index())
df_out = node_list_df.merge(pos, on='Parent', sort=False)
print(df_out)
Child Parent ChildCategory ChildDescription EdgeType Root x \
0 C1 'root'1 X LoremIpsum Strong C1 1.000000
1 C2 C1 X LoremIpsum Strong C1 0.467196
2 C3 C2 Y LoremIpsum Strong C1 -0.055515
3 C4 C2 Y LoremIpsum Strong C1 -0.055515
4 C5 'root'2 X LoremIpsum Strong C5 -0.883338
5 C6 C5 X LoremIpsum Strong C5 -0.345431
6 C7 C6 Y LoremIpsum Weak C5 0.200324
y
0 -0.002704
1 0.149699
2 0.333853
3 0.333853
4 -0.230175
5 -0.363323
6 -0.459552
我有一个 DataFrame 构造为边缘列表和多个子节点和边缘元数据列,大约有 10 000 个条目。
Child | Parent | ChildCategory | ChildDescription | EdgeType | Root |
C1 'root' X Lorem Ipsum Strong C1
C2 C1 X Lorem Ipsum Strong C1
C3 C2 Y Lorem Ipsum Strong C1
C4 C2 Y Lorem Ipsum Strong C1
C5 'root' X Lorem Ipsum Strong C5
C6 C5 X Lorem Ipsum Strong C5
C7 C6 Y Lorem Ipsum Weak C5
... ... ... ... .. ..
我可以使用 networkx 将数据帧转换为图形。
G = nx.from_pandas_edgelist(df,source="Parent",target= "Child",edge_attr=["EdgeType"],create_using = nx.MultiDiGraph())
node_meta_data = ["ChildCategory","ChildDescription","Root"]
for col in node_meta_data:
nx.set_node_attributes(G,dict(zip(node_list_df,df[col].fillna('').tolist())),col)
我现在想做的是获取每组 Root
列的每个节点的二维位置,并将其返回到 DataFrame 列,以便我可以在另一个程序中可视化节点。
如果我要在整个图上做,我可以这样做。
df = pd.DataFrame(index=G.nodes())
for col in node_meta_data:
df[col] = pd.Series(nx.get_node_attributes(G, col))
df['EdgeType'] = nx.get_edge_attributes(G,'EdgeType')
### Here is the problem.
df['position'] = pd.Series(nx.kamada_kawai_layout(G))) ##Without group by root.
#### But I need position per group of root.
....
但是我将如何针对每个根组执行此操作,是否可以以智能方式将 pandas group_by
与 G.subgraph()
一起使用?
编辑:位置列应反映子列的位置。
您似乎想要从每个 root
节点开始的不同子图。为此,您需要更改每个 root
节点的名称,因为必须区分它们。一种方式可能是:
is_root = df.Parent.eq("'root'")
df.loc[is_root, 'Parent'] += is_root.cumsum().astype(str)
这将给出:
print(node_list_df)
Child Parent ChildCategory ChildDescription EdgeType Root
0 C1 'root'1 X LoremIpsum Strong C1
1 C2 C1 X LoremIpsum Strong C1
2 C3 C2 Y LoremIpsum Strong C1
3 C4 C2 Y LoremIpsum Strong C1
4 C5 'root'2 X LoremIpsum Strong C5
5 C6 C5 X LoremIpsum Strong C5
6 C7 C6 Y LoremIpsum Weak C5
现在,如果我们从修改后的数据框构建图,我们现在会得到两个不同的子图,对于来自每个 root
节点的后继者:
G = nx.from_pandas_edgelist(node_list_df,source="Parent",
target= "Child",
create_using = nx.DiGraph())
pos = nx.kamada_kawai_layout(G)
nx.draw(G, pos=pos,
node_color='lightblue',
with_labels=True,
node_size=500)
我们现在可以使用布局中的位置更新数据框:
pos = (pd.DataFrame(pos, index=['x', 'y']).T
.rename_axis('Parent')
.reset_index())
df_out = node_list_df.merge(pos, on='Parent', sort=False)
print(df_out)
Child Parent ChildCategory ChildDescription EdgeType Root x \
0 C1 'root'1 X LoremIpsum Strong C1 1.000000
1 C2 C1 X LoremIpsum Strong C1 0.467196
2 C3 C2 Y LoremIpsum Strong C1 -0.055515
3 C4 C2 Y LoremIpsum Strong C1 -0.055515
4 C5 'root'2 X LoremIpsum Strong C5 -0.883338
5 C6 C5 X LoremIpsum Strong C5 -0.345431
6 C7 C6 Y LoremIpsum Weak C5 0.200324
y
0 -0.002704
1 0.149699
2 0.333853
3 0.333853
4 -0.230175
5 -0.363323
6 -0.459552