SimulationResults#

class bamengine.SimulationResults(role_data=<factory>, economy_data=<factory>, relationship_data=<factory>, config=<factory>, metadata=<factory>)[source]#

Bases: object

Container for simulation results with convenient data access methods.

This class is returned by Simulation.run() and provides structured access to simulation data, including time series of role states, economy-wide metrics, relationship edge data, and metadata about the simulation run.

Variables:
  • role_data (dict) – Time series data for each role, keyed by role name. Each value is a dict of arrays with shape (n_periods, n_agents).

  • economy_data (dict) – Time series of economy-wide metrics with shape (n_periods,).

  • relationship_data (dict) – Time series data for each relationship, keyed by relationship name. Each value is a dict of arrays. When aggregated, arrays have shape (n_periods,). When not aggregated, values are lists of variable-length arrays (one per period).

  • config (dict) – Configuration parameters used for this simulation.

  • metadata (dict) – Run metadata (seed, runtime, n_periods, etc.).

Examples

>>> sim = bam.Simulation.init(n_firms=100, seed=42)
>>> results = sim.run(n_periods=100, collect=True)
>>> # Get all data as DataFrame
>>> df = results.to_dataframe()
>>> # Get specific role data
>>> prod_df = results.get_role_data("Producer")
>>> # Access economy metrics directly
>>> unemployment = results.economy_data["unemployment_rate"]
>>> # Access relationship data (when collected)
>>> results = sim.run(n_periods=100, collect={"LoanBook": True, "aggregate": "sum"})
>>> total_principal = results.relationship_data["LoanBook"]["principal"]
role_data#

Per-role time series data keyed by role name then variable name.

economy_data#

Economy-wide metric time series keyed by metric name.

relationship_data#

Per-relationship time series data keyed by relationship name then field name.

config#

Configuration parameters used for this simulation run.

metadata#

Run metadata including seed, runtime, and period count.

to_dataframe(roles=None, variables=None, include_economy=True, aggregate=None, relationships=None)[source]#

Export results to a pandas DataFrame.

Parameters:
  • roles (list of str, optional) – Specific roles to include. If None, includes all roles.

  • variables (list of str, optional) – Specific variables to include. If None, includes all variables.

  • include_economy (bool, default True) – Whether to include economy-wide metrics.

  • aggregate ({'mean', 'median', 'sum', 'std'}, optional) – How to aggregate agent-level data. If None, returns all agents.

  • relationships (list of str, optional) – Specific relationships to include. If None, includes all relationships with aggregated data. Relationships with non-aggregated data (list of arrays) are skipped with a warning.

Returns:

DataFrame with simulation results. Index is period number. Columns depend on parameters and aggregation method.

Return type:

pd.DataFrame

Raises:

ImportError – If pandas is not installed.

Examples

# Get everything >>> df = results.to_dataframe()

# Get only Producer price and inventory, averaged >>> df = results.to_dataframe( … roles=[“Producer”], variables=[“price”, “inventory”], aggregate=”mean” … )

# Get only economy metrics >>> df = results.to_dataframe(include_economy=True, roles=[])

# Include relationship data >>> df = results.to_dataframe(relationships=[“LoanBook”])

get_role_data(role_name, aggregate=None)[source]#

Get data for a specific role as a DataFrame.

Parameters:
  • role_name (str) – Name of the role (e.g., ‘Producer’, ‘Worker’).

  • aggregate ({'mean', 'median', 'sum', 'std'}, optional) – How to aggregate across agents.

Returns:

DataFrame with the role’s time series data.

Return type:

pd.DataFrame

Raises:

ImportError – If pandas is not installed.

Examples

>>> prod_df = results.get_role_data("Producer")
>>> prod_mean = results.get_role_data("Producer", aggregate="mean")
get_relationship_data(rel_name, aggregate=None)[source]#

Get data for a specific relationship as a DataFrame.

Parameters:
  • rel_name (str) – Name of the relationship (e.g., ‘LoanBook’).

  • aggregate ({'mean', 'median', 'sum', 'std'}, optional) – How to aggregate (only used if data needs re-aggregation).

Returns:

DataFrame with the relationship’s time series data.

Return type:

pd.DataFrame

Raises:

ImportError – If pandas is not installed.

Notes

If the relationship data was collected without aggregation (variable-length arrays per period), this method will issue a warning and return an empty DataFrame. Use results.relationship_data[rel_name] directly for such data.

Examples

>>> loans_df = results.get_relationship_data("LoanBook")
property economy_metrics#

Get economy-wide metrics as a DataFrame.

Returns:

DataFrame with economy time series (unemployment rate, GDP, etc.).

Return type:

pd.DataFrame

Raises:

ImportError – If pandas is not installed.

Examples

>>> econ_df = results.economy_metrics
>>> econ_df[["unemployment_rate", "avg_price"]].plot()
property data#

Unified access to all data (roles + economy + relationships).

Economy data is accessible under the “Economy” key. Relationship data is merged with role data (relationships have unique names so no conflicts).

Returns:

Combined role, economy, and relationship data. Keys are role names, relationship names, and “Economy” for economy metrics.

Return type:

dict

Examples

>>> results.data["Producer"]["price"]
>>> results.data["Economy"]["unemployment_rate"]
>>> results.data["LoanBook"]["principal"]  # if collected
get(name, variable_name, aggregate=None)[source]#

Get a variable as a numpy array.

This provides a convenient way to access simulation data without needing to navigate nested dictionaries.

Parameters:
  • name (str) – Role, relationship, or “Economy” name (e.g., “Producer”, “LoanBook”, “Economy”).

  • variable_name (str) – Variable name (“price”, “principal”, “unemployment_rate”, etc.)

  • aggregate ({'mean', 'sum', 'std', 'median'}, optional) – Aggregation method for 2D data. If provided, reduces (n_periods, n_agents) to (n_periods,).

Returns:

1D array (n_periods,), 2D array (n_periods, n_agents), or list of arrays for non-aggregated relationship data.

Return type:

NDArray or list[NDArray]

Raises:

KeyError – If role/relationship or variable not found.

Examples

>>> productivity = results.get("Producer", "labor_productivity")
>>> avg_prod = results.get("Producer", "labor_productivity", aggregate="mean")
>>> unemployment = results.get("Economy", "unemployment_rate")
>>> total_principal = results.get("LoanBook", "principal")
get_array(name, variable_name, aggregate=None)[source]#

Deprecated: use get() instead.

property summary#

Get summary statistics for key metrics.

Returns:

Summary statistics (mean, std, min, max) for key variables.

Return type:

pd.DataFrame

Raises:

ImportError – If pandas is not installed.

Examples

>>> print(results.summary)
save(filepath)[source]#

Save results to disk (HDF5 or pickle format).

Parameters:

filepath (str) – Path to save file. Use .h5 for HDF5, .pkl for pickle.

Examples

>>> results.save("results.h5")
>>> results.save("results.pkl")
classmethod load(filepath)[source]#

Load results from disk.

Parameters:

filepath (str) – Path to saved results file.

Returns:

Loaded results object.

Return type:

SimulationResults

Examples

>>> results = SimulationResults.load("results.h5")
__repr__()[source]#

String representation showing summary information.

__init__(role_data=<factory>, economy_data=<factory>, relationship_data=<factory>, config=<factory>, metadata=<factory>)#
__getitem__(key)[source]#

Access data via flat ‘Name.variable’ key.

__getattr__(name)[source]#

Attribute-style access to collected data namespaces.

__dir__()[source]#

List available attributes including collected data names.

available()[source]#

List all collected data as ‘Name.variable’ strings.

Returns:

Sorted list of available data keys.

Return type:

list[str]

Examples

>>> results.available()
['Economy.avg_price', 'Economy.inflation', 'Producer.production', ...]