3
3
from abc import ABC , abstractmethod
4
4
from dataclasses import dataclass
5
5
from typing import Callable
6
-
6
+ import pandas as pd
7
7
from causal_testing .data_collection .data_collector import ObservationalDataCollector
8
8
from causal_testing .specification .causal_specification import CausalSpecification
9
9
from causal_testing .testing .base_test_case import BaseTestCase
10
10
from causal_testing .testing .estimators import CubicSplineRegressionEstimator
11
11
12
-
13
12
@dataclass
14
13
class SimulationResult :
15
14
"""Data class holding the data and result metadata of a simulation"""
@@ -18,6 +17,11 @@ class SimulationResult:
18
17
fault : bool
19
18
relationship : str
20
19
20
+ def to_dataframe (self ) -> pd .DataFrame :
21
+ """Convert the simulation result data to a pandas DataFrame"""
22
+ data_as_lists = {k : v if isinstance (v , list ) else [v ] for k ,v in self .data .items ()}
23
+ return pd .DataFrame (data_as_lists )
24
+
21
25
22
26
class SearchAlgorithm (ABC ): # pylint: disable=too-few-public-methods
23
27
"""Class to be inherited with the search algorithm consisting of a search function and the fitness function of the
@@ -87,14 +91,14 @@ def execute(
87
91
88
92
self .simulator .startup ()
89
93
test_result = self .simulator .run_with_config (candidate_test_case )
94
+ test_result_df = test_result .to_dataframe ()
90
95
self .simulator .shutdown ()
91
96
92
97
if custom_data_aggregator is not None :
93
98
if data_collector .data is not None :
94
99
data_collector .data = custom_data_aggregator (data_collector .data , test_result .data )
95
100
else :
96
- data_collector .data = data_collector .data .append (test_result .data , ignore_index = True )
97
-
101
+ data_collector .data = pd .concat ([data_collector .data , test_result_df ], ignore_index = True )
98
102
if test_result .fault :
99
103
print (
100
104
f"Fault found between { surrogate .treatment } causing { surrogate .outcome } . Contradiction with "
0 commit comments