networkx DiGraph属性错误self._succ

时间:2018-02-27 19:34:51

标签: python networkx attributeerror directed-graph

背景:我试图运行另一位研究人员的代码 - 它描述了受地震危害影响的湾区道路网络的交通模型。我是Python的新手,因此非常感谢帮助调试以下错误。

问题:当我尝试运行随文件提供的示例数据的代码时,按照自述文件中的说明,我收到以下错误。

DN0a226926:quick_traffic_model gitanjali$ python mahmodel_road_only.py
You are considering 2 ground-motion intensity maps.
You are considering 1743 different site locations.
You are considering 2 different damage maps (1 per ground-motion intensity map).
Traceback (most recent call last):
  File "mahmodel_road_only.py", line 288, in <module>
main()
  File "mahmodel_road_only.py", line 219, in main
  G = get_graph()
  File "mahmodel_road_only.py", line 157, in get_graph
  G = add_superdistrict_centroids(G)
  File "mahmodel_road_only.py", line 46, in add_superdistrict_centroids
  G.add_node(str(1000000 + i))
  File "/Library/Python/2.7/site-packages/networkx-2.0-py2.7.egg/networkx/classes/digraph.py", line 412, in add_node
if n not in self._succ:
  AttributeError: 'DiGraph' object has no attribute '_succ'

调试:基于其他一些问题,似乎这个错误源于networkx版本(我使用的是2.0)或Python版本(I&#39; m)的问题使用2.7.10)。我经历了the migration guide cited in other questions并且在 mahmodel_road_only.py 中找不到我需要更改的内容。我还检查了digraph.py文件,发现 self._succ 已定义。我还检查了get_graph()的定义,如下所示,它调用networkx,但没有看到任何明显的问题。

def get_graph():
  import networkx
  '''loads full mtc highway graph with dummy links and then adds a few 
  fake centroidal nodes for max flow and traffic assignment'''
G = networkx.read_gpickle("input/graphMTC_CentroidsLength3int.gpickle")
G = add_superdistrict_centroids(G)
assert not G.is_multigraph() # Directed! only one edge between nodes
G = networkx.freeze(G) #prevents edges or nodes to be added or deleted
return G

问题:如何解决此问题?这是改变Python或Networkx版本的问题吗?如果没有,您可以推荐哪些后续步骤进行调试?

1 个答案:

答案 0 :(得分:4)

我认为您的问题类似于AttributeError: 'DiGraph' object has no attribute '_node'

中的问题

问题在于,被调查的图表是在networkx 1.x中创建的,然后是pickle。然后,该图具有networkx 1.x对象具有的属性。我相信这也发生在你身上。

您现在已经打开它,并且您正在将networkx 2.x中的工具应用于该图表。但是这些工具假设它是一个networkx 2.x DiGraph,具有2.x DiGraph中预期的所有属性。特别是它期望为一个节点定义_succ,而1.x DiGraph没有。

所以我认为这有两种方法可行:

短期解决方案 删除networkx 2.x并替换为networkx 1.11。

这不是最佳选择,因为networkx 2.x更强大。此外,已编写为在2.x和1.x中工作的代码(遵循您提到的迁移指南)在1.x中效率较低(例如,将会有1.x代码使用列表和2.x代码正在使用生成器。)

长期解决方案 将1.x图转换为2.x图(我无法轻松测试,因为我目前在我的计算机上没有1.x - 如果有人试图这样做,请发表评论,说明这是否有效以及是否有效您的网络已加权):

#you need commands here to load the 1.x graph G
#
import networkx as nx   #networkx 2.0
H = nx.DiGraph() #or Graph for someone else with this problem.

H.add_nodes_from(G.nodes(data=True))
H.add_edges_from(G.edges(data=True))

data=True用于确保保留任何边/节点权重。 H现在是一个networkx 2.x DiGraph,其边和节点具有G所具有的任何属性。 networkx 2.x命令应该可以使用它。

奖励长期解决方案 联系其他研究人员并警告他/她代码示例现已过时。