networkx DiGraph属性错误self._succ


问题内容

背景信息 :我正在尝试运行另一位研究人员的代码-
它描述了遭受地震危险的湾区道路网的交通模型。我是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版本(我正在使用2.7.10)的问题。我浏览了其他问题中引用的迁移指南,但是在
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版本?如果没有,您可以建议下一步进行调试吗?


问题答案:

我相信您的问题类似于AttributeError中的问题:“ DiGraph”对象没有属性“
_node”

那里的问题是要研究的图形是在networkx 1.x中创建的,然后进行了腌制。然后,该图具有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命令应该可以在其上运行。

更好的长期解决方案 联系其他研究人员,并警告他/她该代码示例现在已过时。