Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

mesa-frames 🚀

mesa-frames is an extension of the mesa framework, designed for complex simulations with thousands of agents. By storing agents in a DataFrame, mesa-frames significantly enhances the performance and scalability of mesa, while maintaining a similar syntax. mesa-frames allows for the use of vectorized functions which significantly speeds up operations whenever simultaneous activation of agents is possible.

Why DataFrames? 📊

DataFrames are optimized for simultaneous operations through SIMD processing. At the moment, mesa-frames supports the use of two main libraries: pandas and Polars.

  • pandas is a popular data-manipulation Python library, developed using C and Cython. pandas is known for its ease of use, allowing for declarative programming and high performance.
  • Polars is a new DataFrame library with a syntax similar to pandas but with several innovations, including a backend implemented in Rust, the Apache Arrow memory format, query optimization, and support for larger-than-memory DataFrames.

The following is a performance graph showing execution time using mesa and mesa-frames for the Boltzmann Wealth model.

Performance Graph with Mesa

Performance Graph without Mesa

(The script used to generate the graph can be found here, but if you want to additionally compare vs Mesa, you have to uncomment mesa_implementation and its label)

Installation

Cloning the Repository

To get started with mesa-frames, first clone the repository from GitHub:

git clone https://github.com/adamamer20/mesa_frames.git
cd mesa_frames

Installing in a Conda Environment

If you want to install it into a new environment:

conda create -n myenv

If you want to install it into an existing environment:

conda activate myenv

Then, to install mesa-frames itself:

pip install -e .

Installing in a Python Virtual Environment

If you want to install it into a new environment:

python3 -m venv myenv
source myenv/bin/activate  # On Windows, use `myenv\Scripts\activate`

If you want to install it into an existing environment:

source myenv/bin/activate  # On Windows, use `myenv\Scripts\activate`

Then, to install mesa-frames itself:

pip install -e .

Usage

Note: mesa-frames is currently in its early stages of development. As such, the usage patterns and API are subject to change. Breaking changes may be introduced. Reports of feedback and issues are encouraged.

You can find the API documentation here.

Creation of an Agent

The agent implementation differs from base mesa. Agents are only defined at the AgentSet level. You can import either AgentSetPandas or AgentSetPolars. As in mesa, you subclass and make sure to call super().__init__(model). You can use the add method or the += operator to add agents to the AgentSet. Most methods mirror the functionality of mesa.AgentSet. Additionally, mesa-frames.AgentSet implements many dunder methods such as AgentSet[mask, attr] to get and set items intuitively. All operations are by default inplace, but if you'd like to use functional programming, mesa-frames implements a fast copy method which aims to reduce memory usage, relying on reference-only and native copy methods.

from mesa-frames import AgentSetPolars

class MoneyAgentPolars(AgentSetPolars):
    def __init__(self, n: int, model: ModelDF):
        super().__init__(model)
        # Adding the agents to the agent set
        self += pl.DataFrame(
            {"unique_id": pl.arange(n, eager=True), "wealth": pl.ones(n, eager=True)}
        )

    def step(self) -> None:
        # The give_money method is called
        self.do("give_money")

    def give_money(self):
        # Active agents are changed to wealthy agents
        self.select(self.wealth > 0)

        # Receiving agents are sampled (only native expressions currently supported)
        other_agents = self.agents.sample(
            n=len(self.active_agents), with_replacement=True
        )

        # Wealth of wealthy is decreased by 1
        self["active", "wealth"] -= 1

        # Compute the income of the other agents (only native expressions currently supported)
        new_wealth = other_agents.group_by("unique_id").len()

        # Add the income to the other agents
        self[new_wealth, "wealth"] += new_wealth["len"]

Creation of the Model

Creation of the model is fairly similar to the process in mesa. You subclass ModelDF and call super().__init__(). The model.agents attribute has the same interface as mesa-frames.AgentSet. You can use += or self.agents.add with a mesa-frames.AgentSet (or a list of AgentSet) to add agents to the model.

from mesa-frames import ModelDF

class MoneyModelDF(ModelDF):
    def __init__(self, N: int, agents_cls):
        super().__init__()
        self.n_agents = N
        self.agents += MoneyAgentPolars(N, self)

    def step(self):
        # Executes the step method for every agentset in self.agents
        self.agents.do("step")

    def run_model(self, n):
        for _ in range(n):
            self.step()

What's Next? 🔮

  • Refine the API to make it more understandable for someone who is already familiar with the mesa package. The goal is to provide a seamless experience for users transitioning to or incorporating mesa-frames.
  • Adding support for default mesa functions to ensure that the standard mesa functionality is preserved.
  • Adding GPU functionality (cuDF and Dask-cuDF).
  • Creating a decorator that will automatically vectorize an existing mesa model. This feature will allow users to easily tap into the performance enhancements that mesa-frames offers without significant code alterations.
  • Creating a unique class for AgentSet, independent of the backend implementation.

License

mesa-frames is made available under the MIT License. This license allows you to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the software, subject to the following conditions:

  • The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
  • The software is provided "as is", without warranty of any kind.

For the full license text, see the LICENSE file in the GitHub repository.

Release files for mesa-frames 0.1.0a0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for mesa-frames 0.1.0a0
File Size Uploaded
mesa_frames-0.1.0a0.tar.gz 282.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for mesa-frames 0.1.0a0
File Interpreter ABI Platform
mesa_frames-0.1.0a0-py3-none-any.whl Python 3 none any Details

Total release size: 341.8 kB

Release files / mesa_frames-0.1.0a0.tar.gz

Download URL mesa_frames-0.1.0a0.tar.gz
Size 282.0 kB
Tags Source
SHA-256 checksum
How to use checksums
2b50c35cc2df9ddc382c4e9a3c12b5fc47c10e3a1140d978422375491acd27d0
BLAKE2b-256 checksum
How to use checksums
47f439aa8de7b01a188e8a8c30db20cd8111202621ff8100dc61b4544db5438c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/5.1.0 CPython/3.12.5

Release files / mesa_frames-0.1.0a0-py3-none-any.whl

Download URL mesa_frames-0.1.0a0-py3-none-any.whl
Size 59.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
3534e2aee919fce28f711864d8e43668a292d6b26e2e015c52558f003d30462c
BLAKE2b-256 checksum
How to use checksums
5f621dba443df57f57f0d27108add6da1e5f6cc1abe7d650a82ac034abcb78b5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/5.1.0 CPython/3.12.5

Release history Release notifications | RSS feed

This release

0.1.0a0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page