首页 > 解决方案 > 如何将 quotient_graph 结果写入文件

问题描述

这是创建“问题”的MWE

>>> A = nx.complete_bipartite_graph(2, 3)
>>> same_neighbors = lambda u, v: (u not in A[v] and v not in A[u] and A[u] == A[v])
>>> B = nx.quotient_graph(A, same_neighbors)
>>> B.nodes()
NodeView((frozenset({0, 1}), frozenset({2, 3, 4})))
>>> B[frozenset({0, 1})]
AtlasView({frozenset({2, 3, 4}): {'weight': 6}})
>>> B.nodes[frozenset({0, 1})]
{'graph': <networkx.classes.graph.Graph object at 0x12b066e80>, 'nnodes': 2, 'nedges': 0, 'density': 0}

我相信graph节点上的这个属性指定了这个节点在原始图中来自的子图,但我不确定。如果有人可以验证那将是很好的。

不管怎样,这个graph属性阻止我使用这个nx.write_graphml函数,因为子图不能用作数据格式。特别是它提出了

networkx.exception.NetworkXError: GraphML writer does not support <class 'networkx.classes.graph.Graph'> as data values.

现在我实际上并不需要graphml文件中的子图,因此仅删除该数据可能是我将图写入文件的最佳方式。做这个的最好方式是什么?

标签: pythonnetworkx

解决方案


我相信节点上的这个图属性指定了这个节点在原始图中来自的子图,但我不确定。如果有人可以验证那将是很好的。

是的,您假设graph属性实际上是根据原始图指定子图是正确的。它在 quotient graph 的文档中有所提及。查看 的描述node_data,你会发现:

node_data (function) – This function takes one argument, B, a set of
nodes in G, and must return a dictionary representing the node data
attributes to set on the node representing B in the quotient graph. If
None, the following node attributes will be set:

- graph, the subgraph of the graph G that this block represents,
- nnodes, the number of nodes in this block,
- nedges, the number of edges within this block,
- density, the density of the subgraph of G that this block represents.

您也可以自己查看子图,方法是输入

for node in B.nodes():
    print("Information for subgraph ", node)
    print(B.nodes[node]['graph'].nodes())

# Output:
# Information for subgraph  frozenset({0, 1})
# Nodes are  [0, 1]
# Information for subgraph  frozenset({2, 3, 4})
# Nodes are  [2, 3, 4]

现在我实际上并不需要 graphml 文件中的子图,因此仅删除该数据可能是我将图写入文件的最佳方式。做这个的最好方式是什么?

您可以简单地创建一个新图并仅添加节点和边,并丢弃任何其他数据。(再次,您假设此信息与以 GraphML 格式写入数据无关,因为您只需要节点和边是正确的)。

在继续之前,让我们检查一下商图的 EdgeView:

B.edges(data=True)
# EdgeDataView([(frozenset({0, 1}), frozenset({2, 3, 4}), {'weight': 6})])

请注意,data边缘是如何weight作为键的字典。这个信息。在后面的代码中会有用。

现在,创建一个新图,并直接从商图中添加边。

H = nx.Graph()

# Here B is the quotient graph
for u,v,d in B.edges(data=True):
    # Notice how the weight is assigned to the new graph
    H.add_edge(u, v, weight=d['weight'])

如果要验证新图是否具有相同的结构,可以使用nx.is_isomorphic进行检查

nx.is_isomorphic(H, B)
# True

现在您可以简单地将图形写入 GraphML 格式

nx.readwrite.graphml.write_graphml(H, "my_graph.graphml")

有关更多信息,您可以查看此 Google Colab Notebook以及上述工作代码。

参考:


推荐阅读