1
0
Fork 0

AbstractExporter

master
Pietro 4 years ago
parent db79fc5b70
commit e32b7c94bc
  1. 38
      PyCTBN/PyCTBN/structure_graph/network_generator.py
  2. 8
      PyCTBN/PyCTBN/structure_graph/trajectory_generator.py
  3. 42
      PyCTBN/PyCTBN/utility/abstract_exporter.py
  4. 68
      PyCTBN/PyCTBN/utility/json_exporter.py
  5. 10
      example.py

@ -3,6 +3,7 @@ from .network_graph import NetworkGraph
from .conditional_intensity_matrix import ConditionalIntensityMatrix from .conditional_intensity_matrix import ConditionalIntensityMatrix
from .set_of_cims import SetOfCims from .set_of_cims import SetOfCims
import numpy as np import numpy as np
import pandas as pd
import os import os
import json import json
@ -105,44 +106,13 @@ class NetworkGenerator(object):
return self._graph return self._graph
@property @property
def cims(self) -> NetworkGraph: def cims(self) -> dict:
return self._cims return self._cims
@property @property
def dyn_str(self) -> list: def dyn_str(self) -> list:
return [{"From": edge[0], "To": edge[1]} for edge in self._graph.edges] return pd.DataFrame([[edge[0], edge[1]] for edge in self._graph.edges], columns = ["From", "To"])
@property @property
def variables(self) -> list: def variables(self) -> list:
return [{"Name": l, "Value": self._vals[i]} for i, l in enumerate(self._labels)] return pd.DataFrame([[l, self._vals[i]] for i, l in enumerate(self._labels)], columns = ["Name", "Value"])
"""Restructure the CIMs object in order to fit the standard JSON file structure
"""
@property
def dyn_cims(self) -> dict:
dyn_cims = {}
for i, l in enumerate(self._labels):
dyn_cims[l] = {}
parents = self._graph.get_ordered_by_indx_set_of_parents(l)[0]
for j, comb in enumerate(self._cims[l].p_combs):
comb_key = ""
if len(parents) != 0:
for k, val in enumerate(comb):
comb_key += parents[k] + "=" + str(val)
if k < len(comb) - 1:
comb_key += ","
else:
comb_key = l
cim = self._cims[l].filter_cims_with_mask(np.array([True for p in parents]), comb)
if len(parents) == 1:
cim = cim[comb[0]].cim
elif len(parents) == 0:
cim = cim[0].cim
else:
cim = cim[0].cim
dyn_cims[l][comb_key] = [dict([(str(i), val) for i, val in enumerate(row)]) for row in cim]
return dyn_cims

@ -33,14 +33,14 @@ class TrajectoryGenerator(object):
self._importer = importer self._importer = importer
self._vnames = self._importer._df_variables.iloc[:, 0].to_list() if importer is not None else [v["Name"] for v in variables] self._vnames = self._importer._df_variables.iloc[:, 0].to_list() if importer is not None else variables.iloc[:, 0].to_list()
self._parents = {} self._parents = {}
for v in self._vnames: for v in self._vnames:
if importer is not None: if importer is not None:
self._parents[v] = self._importer._df_structure.where(self._importer._df_structure["To"] == v).dropna()["From"].tolist() self._parents[v] = self._importer._df_structure.where(self._importer._df_structure["To"] == v).dropna()["From"].tolist()
else: else:
self._parents[v] = [edge["From"] for edge in dyn_str if edge["To"] == v] self._parents[v] = dyn_str.where(dyn_str["To"] == v).dropna()["From"].tolist()
self._cims = {} self._cims = {}
sampled_cims = self._importer._raw_data[0]["dyn.cims"] if importer is not None else dyn_cims sampled_cims = self._importer._raw_data[0]["dyn.cims"] if importer is not None else dyn_cims
@ -56,8 +56,8 @@ class TrajectoryGenerator(object):
sof = SetOfCims(node_id = v, parents_states_number = [self._importer._df_variables.where(self._importer._df_variables["Name"] == p)["Value"] for p in self._parents[v]], sof = SetOfCims(node_id = v, parents_states_number = [self._importer._df_variables.where(self._importer._df_variables["Name"] == p)["Value"] for p in self._parents[v]],
node_states_number = self._importer._df_variables.where(self._importer._df_variables["Name"] == v)["Value"], p_combs = np.array(p_combs), cims = v_cims) node_states_number = self._importer._df_variables.where(self._importer._df_variables["Name"] == v)["Value"], p_combs = np.array(p_combs), cims = v_cims)
else: else:
sof = SetOfCims(node_id = v, parents_states_number = [[variable["Value"] for variable in variables if variable["Name"] == p][0] for p in self._parents[v]], sof = SetOfCims(node_id = v, parents_states_number = [variables.where(variables["Name"] == p)["Value"] for p in self._parents[v]],
node_states_number = [variable for variable in variables if variable["Name"] == v][0]["Value"], p_combs = np.array(p_combs), cims = v_cims) node_states_number = variables.where(variables["Name"] == v)["Value"], p_combs = np.array(p_combs), cims = v_cims)
self._cims[v] = sof self._cims[v] = sof
def CTBN_Sample(self, t_end = -1, max_tr = -1): def CTBN_Sample(self, t_end = -1, max_tr = -1):

@ -0,0 +1,42 @@
import json
import pandas as pd
import os
from abc import ABC, abstractmethod
class AbstractExporter(ABC):
"""Provides the methods to save in json format a network information
along with one or more trajectories generated basing on it
:param _variables: Dataframe containing the nodes labels and cardinalities
:type _variables: pandas.DataFrame
:param _dyn_str: Dataframe containing the structure of the network (edges)
:type _dyn_str: pandas.DataFrame
:param _dyn_cims: It contains, for every variable (label is the key), the SetOfCims object related to it
:type _dyn_cims: dict
:param _trajectories: List of trajectories, that can be added subsequently
:type _trajectories: List
"""
def __init__(self, variables: pd.DataFrame = None, dyn_str: pd.DataFrame = None, dyn_cims: dict = None):
self._variables = variables
self._dyn_str = dyn_str
self._dyn_cims = dyn_cims
self._trajectories = []
def add_trajectory(self, trajectory: list):
"""Add a new trajectory to the current list
:param trajectory: The trajectory to add
:type trajectory: pandas.DataFrame
"""
self._trajectories.append(trajectory)
@abstractmethod
def out_file(self, filename):
"""Create a file in current directory and write on it the previously added data
(variables, dyn_str, dyn_cims and trajectories)
:param filename: Name of the output file (it must include json extension)
:type filename: string
"""

@ -1,37 +1,31 @@
import json import json
import pandas as pd import pandas as pd
import numpy as np
import os import os
class JsonExporter(object): from .abstract_exporter import AbstractExporter
class JsonExporter(AbstractExporter):
"""Provides the methods to save in json format a network information """Provides the methods to save in json format a network information
along with one or more trajectories generated basing on it along with one or more trajectories generated basing on it
:param _variables: List of dictionaries, representing the variables in the network and their cardinality :param _variables: Dataframe containing the nodes labels and cardinalities
:type _variables: List :type _variables: pandas.DataFrame
:param _dyn_str: List of dictionaries, each of which represents an edge ({"From": "", "To": ""}) :param _dyn_str: Dataframe containing the structure of the network (edges)
:type _dyn_str: List :type _dyn_str: pandas.DataFrame
:param _dyn_cims: It contains, for every variable (label is the key), the CIM values related to it :param _dyn_cims: It contains, for every variable (label is the key), the SetOfCims object related to it
:type _dyn_cims: Dict :type _dyn_cims: dict
:param _trajectories: List of trajectories, that can be added subsequently :param _trajectories: List of trajectories, that can be added subsequently
:type _trajectories: List :type _trajectories: List
""" """
def __init__(self, variables, dyn_str, dyn_cims): def __init__(self, variables: pd.DataFrame = None, dyn_str: pd.DataFrame = None, dyn_cims: dict = None):
self._variables = variables self._variables = variables
self._dyn_str = dyn_str self._dyn_str = dyn_str
self._dyn_cims = dyn_cims self._dyn_cims = dyn_cims
self._trajectories = [] self._trajectories = []
def add_trajectory(self, trajectory: list): def out_file(self, filename):
"""Add a new trajectory to the current list
:param trajectory: The trajectory to add. It must already be in json form, and not as pandas.DataFrame
:type trajectory: List
"""
self._trajectories.append(trajectory)
def out_json(self, filename):
"""Create a file in current directory and write on it the previously added data """Create a file in current directory and write on it the previously added data
(variables, dyn_str, dyn_cims and trajectories) (variables, dyn_str, dyn_cims and trajectories)
@ -40,12 +34,42 @@ class JsonExporter(object):
""" """
data = [{ data = [{
"dyn.str": self._dyn_str, "dyn.str": json.loads(self._dyn_str.to_json(orient="records")),
"variables": self._variables, "variables": json.loads(self._variables.to_json(orient="records")),
"dyn.cims": self._dyn_cims, "dyn.cims": self.cims_to_json(),
"samples": self._trajectories "samples": [json.loads(trajectory.to_json(orient="records")) for trajectory in self._trajectories]
}] }]
path = os.getcwd() path = os.getcwd()
with open(path + "/" + filename, "w") as json_file: with open(path + "/" + filename, "w") as json_file:
json.dump(data, json_file) json.dump(data, json_file)
"""Restructure the CIMs object in order to fit the standard JSON file structure
"""
def cims_to_json(self) -> dict:
json_cims = {}
for i, l in enumerate(self._variables.iloc[:, 0].to_list()):
json_cims[l] = {}
parents = self._dyn_str.where(self._dyn_str["To"] == l).dropna()["From"].tolist()
for j, comb in enumerate(self._dyn_cims[l].p_combs):
comb_key = ""
if len(parents) != 0:
for k, val in enumerate(comb):
comb_key += parents[k] + "=" + str(val)
if k < len(comb) - 1:
comb_key += ","
else:
comb_key = l
cim = self._dyn_cims[l].filter_cims_with_mask(np.array([True for p in parents]), comb)
if len(parents) == 1:
cim = cim[comb[0]].cim
elif len(parents) == 0:
cim = cim[0].cim
else:
cim = cim[0].cim
json_cims[l][comb_key] = [dict([(str(i), val) for i, val in enumerate(row)]) for row in cim]
return json_cims

@ -23,11 +23,11 @@ ng.generate_cims(cim_min, cim_max)
# Trajectory Generation # Trajectory Generation
print(ng.dyn_str) print(ng.dyn_str)
e1 = JsonExporter(ng.variables, ng.dyn_str, ng.dyn_cims) e1 = JsonExporter(ng.variables, ng.dyn_str, ng.cims)
tg = TrajectoryGenerator(variables = ng.variables, dyn_str = ng.dyn_str, dyn_cims = ng.dyn_cims) tg = TrajectoryGenerator(variables = ng.variables, dyn_str = ng.dyn_str, dyn_cims = e1.cims_to_json())
sigma = tg.CTBN_Sample(max_tr = 100) sigma = tg.CTBN_Sample(max_tr = 30000)
e1.add_trajectory(tg.to_json()) e1.add_trajectory(sigma)
e1.out_json("example.json") e1.out_file("example.json")
# Network Estimation (Constraint Based) # Network Estimation (Constraint Based)
importer = JsonImporter(file_path="example.json", samples_label='samples', importer = JsonImporter(file_path="example.json", samples_label='samples',