from abc import ABCMeta, abstractmethod
import numpy as np
import pandas as pd
[docs]class NextPointAlgorithm(metaclass=ABCMeta):
def __init__(self):
self.iteration = 0
[docs] @abstractmethod
def set_state(self, state, iteration):
pass
[docs] def restore(self, iteration_state):
pass
[docs] @abstractmethod
def cleanup(self):
pass
[docs] @abstractmethod
def get_param_names(self):
pass
[docs] @abstractmethod
def get_samples_for_iteration(self, iteration):
pass
[docs] @abstractmethod
def get_state(self):
pass
[docs] @abstractmethod
def set_results_for_iteration(self, iteration, results):
pass
[docs] @abstractmethod
def end_condition(self):
pass
[docs] @abstractmethod
def get_final_samples(self):
pass
[docs] def update_iteration(self, iteration):
"""
Update the current iteration state of the algorithm.
"""
self.iteration = iteration
[docs] def prep_for_dict(self, df):
"""
Utility function allowing to transform a DataFrame into a dict removing null values
"""
return df.where(~df.isnull(), other=None).to_dict(orient='list')
[docs] @staticmethod
def sample_from_function(function, N):
return np.array([function.rvs() for i in range(N)])
[docs] def update_summary_table(self, iteration_state, previous_results):
"""
Returns a summary table of the form:
[result1 result2 results_total param1 param2 iteration simIds]
index = sample
Used by OptimTool and IMIS algorithm
"""
results_df = pd.DataFrame.from_dict(iteration_state.results, orient='columns')
results_df.index.name = 'sample'
params_df = pd.DataFrame(iteration_state.samples_for_this_iteration)
params_df.index.name = 'sample'
df = pd.concat((results_df, params_df), axis=1)
df['iteration'] = iteration_state.iteration
previous_results = pd.concat((previous_results, df)).sort_values(by='total', ascending=False)
return previous_results, previous_results[['iteration', 'total']].head(10)
[docs] def get_results_to_cache(self, results):
results['total'] = results.sum(axis=1)
return results.to_dict(orient='list')
[docs] def generate_samples_from_df(self, dfsamples):
# itertuples preserves datatype
# First tuple element is index
# Because parameter names are not necessarily valid python identifiers, have to build my own dictionary here
samples = []
for sample in dfsamples.itertuples():
samples.append({k: v for k, v in zip(dfsamples.columns.values, sample[1:])})
return samples