Metadata-Version: 2.4
Name: penaltyblog
Version: 1.9.0
Summary: Football (soccer) Data & Modelling Made Easy
Author-email: Martin Eastwood <martin.eastwood@gmx.com>
Project-URL: Homepage, https://github.com/martineastwood/penaltyblog
Project-URL: Repository, https://github.com/martineastwood/penaltyblog
Keywords: football,soccer,goals,modelling,dixon coles,poisson,scraper,scraping,backtest,matchflow
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENCE
Requires-Dist: beautifulsoup4
Requires-Dist: cssselect
Requires-Dist: cython
Requires-Dist: fsspec
Requires-Dist: html5lib
Requires-Dist: ipywidgets
Requires-Dist: kaleido
Requires-Dist: lxml
Requires-Dist: matplotlib
Requires-Dist: networkx
Requires-Dist: numpy
Requires-Dist: orjson
Requires-Dist: pandas
Requires-Dist: plotly
Requires-Dist: pulp
Requires-Dist: requests
Requires-Dist: scipy
Requires-Dist: socks
Requires-Dist: statsbombpy
Requires-Dist: tabulate
Requires-Dist: tqdm
Requires-Dist: wrapper-tls-requests
Provides-Extra: dev
Requires-Dist: black>=22.6.0; extra == "dev"
Requires-Dist: build; extra == "dev"
Requires-Dist: coveralls>=3.3.1; extra == "dev"
Requires-Dist: coverage>=6.4.2; extra == "dev"
Requires-Dist: ipython>=8.4.0; extra == "dev"
Requires-Dist: jupyterlab>=3.4.4; extra == "dev"
Requires-Dist: jupyterlab-code-formatter>=1.5.2; extra == "dev"
Requires-Dist: nbsphinx>=0.8.9; extra == "dev"
Requires-Dist: numpydoc>=1.4.0; extra == "dev"
Requires-Dist: pre-commit>=2.20.0; extra == "dev"
Requires-Dist: Pygments>=2.12.0; extra == "dev"
Requires-Dist: pytest>=7.1.2; extra == "dev"
Requires-Dist: pytest-vcr; extra == "dev"
Requires-Dist: setuptools>=75.6.0; extra == "dev"
Requires-Dist: Sphinx>=5.1.1; extra == "dev"
Requires-Dist: sphinx-rtd-theme>=1.0.0; extra == "dev"
Requires-Dist: types-requests>=2.28.11; extra == "dev"
Requires-Dist: vcrpy; extra == "dev"
Provides-Extra: s3
Requires-Dist: s3fs; extra == "s3"
Provides-Extra: gcs
Requires-Dist: gcsfs; extra == "gcs"
Requires-Dist: gcloud; extra == "gcs"
Provides-Extra: azure
Requires-Dist: adlfs; extra == "azure"
Provides-Extra: cloud
Requires-Dist: s3fs; extra == "cloud"
Requires-Dist: gcsfs; extra == "cloud"
Requires-Dist: adlfs; extra == "cloud"
Requires-Dist: gcloud; extra == "cloud"
Dynamic: license-file

<img src="https://raw.githubusercontent.com/martineastwood/penaltyblog/refs/heads/master/logo.png" width="0" height="0" style="display:none;"/>

<meta property="og:image" content="https://raw.githubusercontent.com/martineastwood/penaltyblog/refs/heads/master/logo.png" />
<meta property="og:image:alt" content="penaltyblog python package for soccer modeling" />
<meta name="twitter:image" content="https://raw.githubusercontent.com/martineastwood/penaltyblog/refs/heads/master/logo.png">
<meta name="twitter:card" content="summary_large_image">

# Penalty Blog

<div align="center">

<a href="">[![Python Version](https://img.shields.io/pypi/pyversions/penaltyblog)](https://pypi.org/project/penaltyblog/)</a>
<a href="https://codecov.io/github/martineastwood/penaltyblog" >
<img src="https://codecov.io/github/martineastwood/penaltyblog/branch/master/graph/badge.svg?token=P0WDHRGIG2"/>
</a>
<a href="">[![PyPI](https://img.shields.io/pypi/v/penaltyblog.svg)](https://pypi.org/project/penaltyblog/)</a>
<a href="">[![Downloads](https://static.pepy.tech/badge/penaltyblog)](https://pepy.tech/project/penaltyblog)</a>
<a href="">[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)</a>
<a href="">[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)</a>
<a href="">[![Code style: pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white)](https://github.com/pre-commit/pre-commit)</a>

</div>

<div align="center">
  <img src="logo.png" alt="Penalty Blog Logo" width="200">
</div>

# penaltyblog: Football Data & Modelling Made Easy

**penaltyblog** is a production-ready Python package designed for football (soccer) analytics, providing powerful tools from [pena.lt/y/blog](https://pena.lt/y/blog) for data analysis, outcome modelling, and betting insights. Optimized with Cython, **penaltyblog** delivers high-performance modelling to power faster, efficient predictions.

## Features

- 🔄 **Streamline JSON Workflows with MatchFlow:** Process nested football data using a lazy, streaming pipeline built for JSON. Filter, select, flatten, join, group, and summarize large datasets without loading everything into memory.
- 🔌 **Connect to Professional APIs:** Seamlessly stream and filter data directly from industry leaders, like StatsBomb and Opta. Query matches, events, and stats using lazy loading without handling massive JSON dumps.
- 📊 **Model Matches Efficiently:** High-performance implementations of Poisson, Bivariate Poisson, Dixon-Coles, and other advanced statistical models, optimized with Cython for rapid analysis.
- 🧠 **Advanced Bayesian Modelling:** Full posterior distributions for match outcomes using MCMC sampling. Includes Hierarchical Bayesian models to automatically learn league-wide variances and handle parameter uncertainty.
- ⚽ **Scrape Data:** Collect match statistics from sources like Understat, Club Elo, and Fantasy Premier League.
- 💰 **Bet Smarter:** Precisely estimate probabilities for Asian handicaps, over/under totals, match outcomes, and more.
- 🏆 **Rank Teams:** Evaluate team strengths with sophisticated methods including Elo, Massey, Colley, and Pi ratings.
- 📈 **Decode Bookmaker Odds:** Accurately extract implied probabilities by removing bookmaker margins (overrounds).
- 🎯 **Fantasy Football Optimisation:** Mathematically optimize your fantasy football squad to maximize performance.
- 🎨 **Visualize with Style:** Create publication-ready pitch visualizations and data flow diagrams with customizable themes, supporting multiple data providers and flexible layouts.

Take your football analytics and betting strategy to the next level with **penaltyblog** 🚀

## Installation

```bash
pip install penaltyblog
```

## 🚀 Quick Start - Try it Now!

Run these examples directly in your browser (no installation required):

| Example                               | Description                                                              | Colab                                                                                                                                                               |
| ------------------------------------- | ------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Predict Soccer Match Results**      | Build a match prediction model from scratch                              | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/drive/1GjrDG_iq_9_lxEQK_aBmr-jCCCnFt0v7?usp=sharing) |
| **Process Soccer Data the Easy Way**  | Lazy processing of football data using Matchflow                         | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/drive/1rRJV8mNOTLTXmn5cOGT4faxIwIP44pC-?usp=sharing) |
| **Calculate Massey Ratings**          | Calculate teams' attack and defense strengths                            | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/drive/1d_WPJwQgrogeSI9oIO9fY8s18CPPZ8nL?usp=sharing) |
| **Use Pi Ratings**                    | Like Elo ratings, but better                                             | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/drive/12qEDCNYG-FFHOJ_kURe0cm80sScandyh?usp=sharing) |
| **Create Interactive Charts**         | Create your own interactive football vizualisations                      | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/drive/1xFfIdvmbFcjHlS_2eHEu3NxD-xLNrbpY?usp=sharing) |
| **Work Directly With Statsbomb Data** | Connect directly to Statsbomb's API, including their free open data sets | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/drive/1xFfIdvmbFcjHlS_2eHEu3NxD-xLNrbpY?usp=sharing) |
| **Calculate Implied Probabilities**   | Calculate implied probabilities from bookmaker's odds                    | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/drive/1o-tOetyWmSY_1WczN8WhWsl62Uz5T65F?usp=sharing) |

## Documentation

Learn more about how to utilize `penaltyblog` by exploring the [official documentation](https://penaltyblog.readthedocs.io/en/latest/) and detailed examples:

- [Processing football event data with MatchFlow](https://penaltyblog.readthedocs.io/en/latest/matchflow/index.html)
- [Scraping football data](https://penaltyblog.readthedocs.io/en/latest/scrapers/index.html)
- [Predicting football matches and betting markets](https://penaltyblog.readthedocs.io/en/latest/models/index.html)
- [Estimating implied odds from bookmaker prices](https://penaltyblog.readthedocs.io/en/latest/implied/index.html)
- [Calculating Massey, Colley, Pi, and Elo ratings](https://penaltyblog.readthedocs.io/en/latest/ratings/index.html)
- [Calculating metrics such as Ranked Probability Scores](https://penaltyblog.readthedocs.io/en/latest/metrics/index.html)

## Why Penaltyblog?

Unlike many football analytics resources that are academic, one-off, or hard to scale, `penaltyblog` is designed from the ground up to be **production-ready**, **performance-optimized**, and **practically useful**.

It combines advanced statistical models (including **Bayesian** and **Hierarchical Bayesian** variants), efficient implementations (via **Cython**), and real-world workflows, from scraping public data to modelling outcomes and optimising fantasy teams.

The project is maintained by [Martin Eastwood](https://pena.lt/y/about), a data scientist focused on the intersection of high-performance computing and sports analytics. `penaltyblog` aims to provide the community with a robust, audited foundation for advanced modeling.

## Community & Contributions

I am always interested in seeing how `penaltyblog` is being applied in research and industry. If you have feedback, bug reports, or want to collaborate on new features, feel free to:

- Open an Issue [here](https://github.com/martineastwood/penaltyblog/issues)
- Get in touch [here](https://pena.lt/y/contact)
