Python 从数据帧构造NetworkX图
我想从一个简单的数据框创建一些NetworkX图:Python 从数据帧构造NetworkX图,python,pandas,networkx,Python,Pandas,Networkx,我想从一个简单的数据框创建一些NetworkX图: Loc 1 Loc 2 Loc 3 Loc 4 Loc 5 Loc 6 Loc 7 Foo 0 0 1 1 0 0 0 Bar 0 0 1 1 0 1 1 Baz 0 0 1 0
Loc 1 Loc 2 Loc 3 Loc 4 Loc 5 Loc 6 Loc 7
Foo 0 0 1 1 0 0 0
Bar 0 0 1 1 0 1 1
Baz 0 0 1 0 0 0 0
Bat 0 0 1 0 0 1 0
Quux 1 0 0 0 0 0 0
其中Foo…
为索引,Loc 1
至Loc 7
为列。但是,转换为Numpy矩阵或重新排列似乎无法为nx.Graph()
生成输入。是否有实现这一目标的标准战略?我并不反对将Pandas-->dumping to CSV-->导入NetworkX中的数据重新格式化,但似乎我应该能够从索引中生成边,并从值中生成节点。(节点和边),也许*您想传递它:
In [11]: df2 = pd.concat([df, df.T]).fillna(0)
注意:索引和列的顺序必须相同
这不会将列/索引名称传递给图形,如果您想这样做,您可以使用(您可能必须小心重复,这在pandas的数据帧中是允许的):
*对于所需的图形,列和索引究竟代表什么还不清楚。回答有点晚,但是,在这种情况下,理想情况下,对于简单的有向图,格式如下所示:
+----------+---------+---------+
| Source | Target | Weight |
+==========+=========+=========+
| Node_1 | Node_2 | 0.2 |
+----------+---------+---------+
| Node_2 | Node_1 | 0.6 |
+----------+---------+---------+
如果您使用的是邻接矩阵,那么Andy Hayden是对的,您应该注意正确的格式。因为在你的问题中你使用了0和1,我想你会想看到一个无向图。首先,这似乎有悖常理,因为你说索引表示一个人,列表示一个人所属的组,但从另一方面来说,组(成员)属于一个人也是正确的。按照这个逻辑,实际上应该将组放在索引中,将人员也放在列中
只是一个旁注:您还可以在有向图的意义上定义这个问题,例如,您希望可视化层次类别的关联网络。在那里,从Samwise Gamgee到Hobbit的关联通常比在另一个方向上更强(因为Frodo Baggins更可能是Hobbit原型)您也可以使用scipy创建如下方形矩阵:
import scipy.sparse as sp
cols = df.columns
X = sp.csr_matrix(df.astype(int).values)
Xc = X.T * X # multiply sparse matrix
Xc.setdiag(0) # reset diagonal
# create dataframe from co-occurence matrix in dense format
df = pd.DataFrame(Xc.todense(), index=cols, columns=cols)
稍后,您可以从dataframe创建边缘列表并将其导入Networkx:
df = df.stack().reset_index()
df.columns = ['source', 'target', 'weight']
df = df[df['weight'] != 0] # remove non-connected nodes
g = nx.from_pandas_edgelist(df, 'source', 'target', ['weight'])
索引表示一个人,列表示一个人所属的组。
import scipy.sparse as sp
cols = df.columns
X = sp.csr_matrix(df.astype(int).values)
Xc = X.T * X # multiply sparse matrix
Xc.setdiag(0) # reset diagonal
# create dataframe from co-occurence matrix in dense format
df = pd.DataFrame(Xc.todense(), index=cols, columns=cols)
df = df.stack().reset_index()
df.columns = ['source', 'target', 'weight']
df = df[df['weight'] != 0] # remove non-connected nodes
g = nx.from_pandas_edgelist(df, 'source', 'target', ['weight'])