我有以下形式的pandas数据框, df ,
A B C D
A 0 0.5 0.5 0
B 1 0 0 0
C 0.8 0 0 0.2
D 0 0 1 0
我正在尝试从中创建一个networkx图。我尝试了以下代码变体:
A)
G=networkx.from_pandas_adjacency(df)
G=networkx.DiGraph(G)
B)
G=networkx.from_pandas_adjacency(df, create_using=networkx.DiGraph())
然而,最终发生的事情是图形对象:
(对于选项A)基本上只取两个给定节点之间的两个平行边中的一个值,删除另一个。
(对于选项B)从任意两个给定节点之间的两个平行边中取一个值,作为两个边的值。
例如,
print( list ( filter ( lambda x: x[0]=='A' and x[1] == 'B', list(G.edges.data()) ) ) )
和
print( list ( filter ( lambda x: x[0]=='B' and x[1] == 'A', list(G.edges.data()) ) ) )
为选项A打印1和[]。 为选项B打印两个1。
如何解决此问题?
答案 0 :(得分:2)
尝试使用numpy作为解决方法。
G = nx.from_numpy_matrix(df.values, parallel_edges=True,
create_using=nx.MultiDiGraph())
# Because we use numpy, labels need to be reset
label_mapping = {0: "A", 1: "B", 2: "C", 3: "D"}
G = nx.relabel_nodes(G, label_mapping)
G.edges(data=True)
OutMultiEdgeDataView([('A', 'B', {'weight': 0.5}),
('A', 'C', {'weight': 0.5}),
('B', 'A', {'weight': 1.0}),
('C', 'A', {'weight': 0.8}),
('C', 'D', {'weight': 0.2}),
('D', 'C', {'weight': 1.0})])
在更一般的情况下,要获得label_mapping
,您可以使用
label_mapping = {idx: val for idx, val in enumerate(df.columns)}
这似乎是networkx 2.0
中的错误。他们将在2.1中修复它。有关详细信息,请参阅此issue。