import pandas as pd import numpy as np import networkx as nx import os try: import graph_tool as gt except: pass def parse_evalne_output(string): def foo(x): try: return eval(x) except: return x modif = string.split("---------------------------")[-1] results = modif.split("\n \n") logs = [] for log in results: log = log.strip().split("\n") name, data = log[0].strip(":"), log[1:] data = [d.split("\t") for d in data] data = [[i.strip().strip(":") for i in d] for d in data] data = dict([[d[0], foo(d[1])] for d in data]) data["name"] =name logs.append(data) return pd.DataFrame.from_records(logs) def get_centroid(gdf,key_id): gdf["centroid_"] = gdf.centroid.apply(lambda coord: [coord.x,coord.y]) return dict(gdf[(key_id + " centroid_").split()].values) def get_labels(gdf,key_id,key_label): return dict(gdf[(key_id + " " + key_label).split()].values) def to_networkx(df): nodelist = df.user_loc.unique().tolist() nodelist.extend(df.fr_loc.unique().tolist()) G = nx.from_pandas_edgelist(df,source = "user_loc",target="fr_loc",edge_attr="weight") return G def get_prop_type(value, key=None): """ Performs typing and value conversion for the graph_tool PropertyMap class. If a key is provided, it also ensures the key is in a format that can be used with the PropertyMap. Returns a tuple, (type name, value, key) """ # Deal with the value if isinstance(value, bool): tname = 'bool' elif isinstance(value, int): tname = 'float' value = float(value) elif isinstance(value, float): tname = 'float' elif isinstance(value, dict): tname = 'object' else: tname = 'string' value = str(value) return tname, value, key def nx2gt(nxG): """ Converts a networkx graph to a graph-tool graph. Code from http://bbengfort.github.io/snippets/2016/06/23/graph-tool-from-networkx.html """ # Phase 0: Create a directed or undirected graph-tool Graph gtG = gt.Graph(directed=nxG.is_directed()) # Add the Graph properties as "internal properties" for key, value in nxG.graph.items(): # Convert the value and key into a type for graph-tool tname, value, key = get_prop_type(value, key) prop = gtG.new_graph_property(tname) # Create the PropertyMap gtG.graph_properties[key] = prop # Set the PropertyMap gtG.graph_properties[key] = value # Set the actual value # Phase 1: Add the vertex and edge property maps # Go through all nodes and edges and add seen properties # Add the node properties first nprops = set() # cache keys to only add properties once for node, data in nxG.nodes(data=True): # Go through all the properties if not seen and add them. for key, val in data.items(): if key in nprops: continue # Skip properties already added # Convert the value and key into a type for graph-tool tname, _, key = get_prop_type(val, key) prop = gtG.new_vertex_property(tname) # Create the PropertyMap gtG.vertex_properties[key] = prop # Set the PropertyMap # Add the key to the already seen properties nprops.add(key) # Also add the node id: in NetworkX a node can be any hashable type, but # in graph-tool node are defined as indices. So we capture any strings # in a special PropertyMap called 'id' -- modify as needed! gtG.vertex_properties['id'] = gtG.new_vertex_property('string') # Add the edge properties second eprops = set() # cache keys to only add properties once for src, dst, data in nxG.edges(data=True): # Go through all the edge properties if not seen and add them. for key, val in data.items(): if key in eprops: continue # Skip properties already added # Convert the value and key into a type for graph-tool tname, _, key = get_prop_type(val, key) prop = gtG.new_edge_property(tname) # Create the PropertyMap gtG.edge_properties[key] = prop # Set the PropertyMap # Add the key to the already seen properties eprops.add(key) # Phase 2: Actually add all the nodes and vertices with their properties # Add the nodes vertices = {} # vertex mapping for tracking edges later for node, data in nxG.nodes(data=True): # Create the vertex and annotate for our edges later v = gtG.add_vertex() vertices[node] = v # Set the vertex properties, not forgetting the id property data['id'] = str(node) for key, value in data.items(): gtG.vp[key][v] = value # vp is short for vertex_properties # Add the edges for src, dst, data in nxG.edges(data=True): # Look up the vertex structs from our vertices mapping and add edge. e = gtG.add_edge(vertices[src], vertices[dst]) # Add the edge properties for key, value in data.items(): gtG.ep[key][e] = value # ep is short for edge_properties # Done, finally! return gtG