2015-04-15 24 views
16

Tôi có một ma trận kề được lưu trữ như một pandas.DataFrame:igraph Graph từ NumPy hay gấu trúc kề ma trận

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() 

Tôi muốn tạo ra một igraph.Graph từ một trong hai hoặc ma trận kề pandasnumpy. Trong một thế giới lý tưởng, các nút sẽ được đặt tên như mong đợi.

Điều này có khả thi không? The tutorial dường như im lặng về vấn đề này.

+0

Nói đúng ra, [ma trận kề] (http: // en.wikipedia.org/wiki/Adjacency_matrix) là boolean. Các giá trị trong 'a_numpy' thực sự có ý nghĩa gì? Chúng có trọng lượng kết nối không? –

+0

@ali_m Tôi có nghĩa là chúng có nghĩa là trọng lượng cạnh. – LondonRob

Trả lời

20

Trong igraph bạn có thể sử dụng igraph.Graph.Adjacency để tạo ra một biểu đồ từ một ma trận kề mà không cần phải sử dụng zip. Có một số điều cần lưu ý khi một ma trận kề trọng số được sử dụng và lưu trữ trong một số np.array hoặc pd.DataFrame.

  • igraph.Graph.Adjacency không thể lấy một np.array như là đối số, nhưng điều đó có thể dễ dàng giải quyết bằng tolist.

  • Số nguyên trong ma trận kề được hiểu là số cạnh giữa các nút thay vì trọng số, được giải quyết bằng cách sử dụng kề dưới dạng boolean.

Một ví dụ về làm thế nào để làm điều đó:

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 

Bạn có thể tái tạo lại dataframe kề của bạn sử dụng get_adjacency bởi:

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 
+1

Hoàn hảo! 1 cho thực tế là 'Adjacency' diễn giải các con số dưới dạng một số liên kết, không phải là trọng số liên kết. – LondonRob

+0

Bạn sẽ chuyển đổi đồ thị này thành phiên bản được chỉ định như thế nào nếu các hàng là các nút 'từ' và các cột là các nút 'đến'. –

11

Nói đúng, adjacency matrix là boolean, với 1 cho biết sự hiện diện của kết nối và 0 cho biết sự vắng mặt. Vì nhiều giá trị trong ma trận a_numpy của bạn là> 1, tôi sẽ giả định rằng chúng tương ứng với trọng số cạnh trong biểu đồ của bạn.

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) 

enter image description here

Các vấn đề liên quan