python numpy pandas igraph

python - Gráfica igraph de matriz de adyacencia numpy o pandas



plt title python 3 (2)

En igraph puede usar igraph.Graph.Adjacency para crear un gráfico a partir de una matriz de adyacencia sin tener que usar zip . Hay algunas cosas que se deben tener en cuenta cuando una matriz de adyacencia ponderada se utiliza y almacena en un np.array o pd.DataFrame .

  • igraph.Graph.Adjacency no puede tomar un np.array como argumento, pero eso se resuelve fácilmente usando tolist .

  • Los enteros en la matriz de adyacencia se interpretan como un número de bordes entre nodos en lugar de pesos, y se resuelven utilizando la adyacencia como booleano.

Un ejemplo de cómo hacerlo:

import igraph import pandas as pd node_names = [''A'', ''B'', ''C''] a = pd.DataFrame([[1,2,3],[3,1,1],[4,0,2]], index=node_names, columns=node_names) # Get the values as np.array, it''s more convenenient. A = a.values # Create graph, A.astype(bool).tolist() or (A / A).tolist() can also be used. g = igraph.Graph.Adjacency((A > 0).tolist()) # Add edge weights and node labels. g.es[''weight''] = A[A.nonzero()] g.vs[''label''] = node_names # or a.index/a.columns

Puede reconstruir su marco de datos de adyacencia usando get_adjacency de la siguiente manera:

df_from_g = pd.DataFrame(g.get_adjacency(attribute=''weight'').data, columns=g.vs[''label''], index=g.vs[''label'']) (df_from_g == a).all().all() # --> True

Tengo una matriz de adyacencia almacenada como pandas.DataFrame :

node_names = [''A'', ''B'', ''C''] a = pd.DataFrame([[1,2,3],[3,1,1],[4,0,2]], index=node_names, columns=node_names) a_numpy = a.as_matrix()

Me gustaría crear un igraph.Graph desde las pandas o las matrices de adyacencia numpy . En un mundo ideal, los nodos serían nombrados como se esperaba.

es posible? El tutorial parece guardar silencio sobre el tema.


Estrictamente hablando, una matriz de adyacencia es booleana, con 1 que indica la presencia de una conexión y 0 que indica la ausencia. Dado que muchos de los valores en su matriz a_numpy son> 1, asumiré que corresponden a pesos de borde en su gráfica.

import igraph # get the row, col indices of the non-zero elements in your adjacency matrix conn_indices = np.where(a_numpy) # get the weights corresponding to these indices weights = a_numpy[conn_indices] # a sequence of (i, j) tuples, each corresponding to an edge from i -> j edges = zip(*conn_indices) # initialize the graph from the edge sequence G = igraph.Graph(edges=edges, directed=True) # assign node names and weights to be attributes of the vertices and edges # respectively G.vs[''label''] = node_names G.es[''weight''] = weights # I will also assign the weights to the ''width'' attribute of the edges. this # means that igraph.plot will set the line thicknesses according to the edge # weights G.es[''width''] = weights # plot the graph, just for fun igraph.plot(G, layout="rt", labels=True, margin=80)