Skip to main content

chickenstats

Hero image - scatter plot with drumsticks and tooltips

PyPI - Version PyPI - Python Version tests codecov GitHub Release Date - Published_At GitHub License


About

  • Scrape & manipulate data from various NHL endpoints with chickenstats.chicken_nhl, including play-by-play, rosters, and shifts data, including score-adjusted shot metrics
  • Augment play-by-play data & generate custom aggregations from raw csv files downloaded from Evolving-Hockey (subscription required) with chickenstats.evolving_hockey

For more in-depth explanations, tutorials, & detailed reference materials, consult the Documentation.


Compatibility

chickenstats requires Python 3.10 or greater & runs on the latest stable versions of Linux, Mac, & Windows operating systems.


Installation

Very simple - install using PyPi. Best practice is to develop in an isolated virtual environment (conda or otherwise), but who's a chicken to judge?

pip install chickenstats

To confirm installation & the latest version (1.8.0):

pip show chickenstats

Optional extras

Core installation includes only the essentials. Install extras for additional output formats or features:

Extra Command What it adds
pandas pip install chickenstats[pandas] Pandas DataFrame output (backend="pandas")
pyarrow pip install chickenstats[pyarrow] PyArrow Table output (backend="pyarrow")
plotting pip install chickenstats[plotting] Matplotlib, Bokeh, Plotly, Seaborn chart helpers

Usage

chickenstats is structured as two underlying modules, each used with different data sources:

  • chickenstats.chicken_nhl
  • chickenstats.evolving_hockey

The packages and resulting outputs are largely interchangeable, with similar fields across chicken_nhl and evolving_hockey, including high-danger scoring chances, and score- and venue-adjusted fenwick and corsi.

Feel free to use whichever package and data source that you prefer. If you have questions about differences between packages, you can find me on Bluesky at @chickenandstats.com or email me at chicken@chickenandstats.com.

Please note that chickenstats is under active development - features will continue to be added or modified over time.

chicken_nhl

chickenstats.chicken_nhl allows you to scrape play-by-play data and aggregate individual, line, and team statistics. After importing the module, scrape the schedule for game IDs, then play-by-play data for your team of choice:

from chickenstats import Season, Scraper
import polars as pl

season = Season(2025)

schedule = season.schedule("NSH")
game_ids = schedule.filter(pl.col("game_state") == "OFF")["game_id"].to_list()

scraper = Scraper(game_ids)

play_by_play = scraper.play_by_play

You can then aggregate the play-by-play data for individual and on-ice statistics with one line of code:

stats = scraper.stats

It's very easy to introduce additional detail to, as well as change the level of, aggregations, including for season-level statistics accounting for teammates on-ice:

stats = scraper.prep_stats(level="season", teammates=True).stats

[!TIP] The Scraper object saves the prior aggregation to the scraper.stats attribute, so it needs to be reset. Then the attribute can be re-called, with a different level of aggregation

There is similar functionality for forward line / defensive pairing stats:

forward_lines = scraper.prep_lines(position="f").lines # Forward lines, defaults to game-level

defense_lines = scraper.prep_lines(position="d", level="season").lines # Defensive pairings, at season level

[!TIP] This step isn't strictly necessary for the forwards - they're the default line aggregation. Provide "d" instead of "f" for defensive line stats

As well as for team stats:

team_stats = scraper.team_stats

For additional information on usage and functionality, consult the relevant user guide

evolving_hockey

The chickenstats.evolving_hockey module manipulates raw csv files downloaded from Evolving-Hockey. Using their original shifts & play-by-play data, users can add additional information & aggregate for individual & on-ice statistics, including high-danger shooting events, faceoffs, & changes.

First, prep a play-by-play dataframe using raw play-by-play and shifts CSV files from the Evolving-Hockey website:

import polars as pl
from chickenstats.evolving_hockey import prep_pbp, prep_stats, prep_lines

raw_shifts = pl.read_csv('./raw_shifts.csv')
raw_pbp = pl.read_csv('./raw_pbp.csv')

play_by_play = prep_pbp(raw_pbp, raw_shifts)

You can use the play_by_play dataframe in various aggregations. This will return individual game statistics, including on-ice (e.g., GF, CF) & usage (i.e., zone starts), accounting for teammates & opposition on-ice:

individual_game = prep_stats(play_by_play, level='game', teammates=True, opposition=True)

This will return game statistics for forward-line combinations, accounting for opponents on-ice:

forward_lines = prep_lines(play_by_play, level='game', position='f', opposition=True)

For additional information on usage and functionality, consult the relevant user guide


Help

If you need help with any aspect of chickenstats, from installation to usage, please don't hesitate to reach out! You can find me on Bluesky at @chickenandstats.com or email me at chicken@chickenandstats.com.

Please report any bugs or issues via the chickenstats issues page, where you can also post feature requests.


Contributing

Contributions are welcome! Please read CONTRIBUTING.md for development setup, commit conventions, and the PR process. Found a bug or have a feature request? Open an issue.

This project follows a Code of Conduct. By participating, you are expected to uphold it.


Acknowledgements

chickenstats wouldn't be possible without the support & efforts of countless others. I am obviously extremely grateful, even if there are too many of you to thank individually. However, this chicken will do his best.

First & foremost is my wife - the lovely Mrs. Chicken has been patient, understanding, & supportive throughout the countless hours of development, sometimes to her detriment.

Sincere apologies to the friends & family that have put up with me since my entry into Python, programming, & data analysis in January 2021. Thank you for being excited for me & with me throughout all of this, especially when you've had to fake it...

Thank you to the hockey analytics community on (the artist formerly known as) Twitter. You're producing & reacting to cutting-edge statistical analyses, while providing a supportive, welcoming environment for newcomers. Thank y'all for everything that you do. This is by no means exhaustive, but there are a few people worth calling out specifically:

I'm also grateful to the thriving community of Python educators & open-source contributors on Twitter. Thank y'all for your knowledge & practical advice. Matt Harrison (@mharrison) deserves a special mention for his books on Pandas and XGBoost, both of which are available at his online store. Again, not exhaustive, but others worth thanking individually:

Finally, this library depends on a host of other open-source packages. chickenstats is possible because of the efforts of thousands of individuals, represented below:

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

chickenstats-1.8.0.tar.gz (788.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

chickenstats-1.8.0-py3-none-any.whl (194.6 kB view details)

Uploaded Python 3

File details

Details for the file chickenstats-1.8.0.tar.gz.

File metadata

  • Download URL: chickenstats-1.8.0.tar.gz
  • Upload date:
  • Size: 788.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for chickenstats-1.8.0.tar.gz
Algorithm Hash digest
SHA256 64a2d17b220b935e5c749b978b826c4e2479cd40812b82627c9f3ad564aebbec
MD5 2a9392b4e0468b81f47c87fbd7ee6914
BLAKE2b-256 9536fa7a7ee72f57a0ec266ac8914da7484dd4fe453042a6d391a7619af71dd5

See more details on using hashes here.

File details

Details for the file chickenstats-1.8.0-py3-none-any.whl.

File metadata

  • Download URL: chickenstats-1.8.0-py3-none-any.whl
  • Upload date:
  • Size: 194.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for chickenstats-1.8.0-py3-none-any.whl
Algorithm Hash digest
SHA256 f8bd8eedf84cc02196533669e603533d45b40b699946a163381a46c82381efe8
MD5 4e654e3235b0b9a6e6297c0d1cb2e9b1
BLAKE2b-256 7722c7b8a2ef1f11dd6273233f365d5bc44b329f78a24e107c2b8da72ad65e0a

See more details on using hashes here.

Release history Release notifications | RSS feed

1.8.1

2 files

This release

1.8.0 This release

2 files

1.7.9.29

2 files

1.7.9.28

2 files

1.7.9.27

2 files

1.7.9.26

2 files

1.7.9.25

2 files

1.7.9.24

2 files

1.7.9.23

2 files

1.7.9.22

2 files

1.7.9.21

2 files

1.7.9.20

2 files

1.7.9.19

2 files

1.7.9.17

2 files

1.7.9.16

2 files

1.7.9.15

2 files

1.7.9.14

2 files

1.7.9.13

1 file

1.7.9.12

2 files

1.7.9.11

2 files

1.7.9.10

2 files

1.7.9.8

2 files

1.7.9.7

2 files

1.7.9.6

2 files

1.7.9.5

2 files

1.7.9.4

2 files

1.7.9.3

2 files

1.7.9.2

2 files

1.7.9.1

2 files

1.7.9

2 files

1.7.8

2 files

1.7.7

2 files

1.7.6

2 files

1.7.5

2 files

1.7.4

2 files

1.7.3.8.9.10.9

2 files

1.7.3.8.9.10.8

2 files

1.7.3.8.9.10.7

2 files

1.7.3.8.9.10.6

2 files

1.7.3.8.9.10.5

2 files

1.7.3.8.9.10.4

2 files

1.7.3.8.9.10.3

2 files

1.7.3.8.9.10.2

2 files

1.7.3.8.9.10.1

2 files

1.7.3.8.9.10

2 files

1.7.3.8.9.9

2 files

1.7.3.8.9.8

2 files

1.7.3.8.9.7

2 files

1.7.3.8.9.6

2 files

1.7.3.8.9.5

2 files

1.7.3.8.9.4

2 files

1.7.3.8.9.3

2 files

1.7.3.8.9.2

2 files

1.7.3.8.9.1

2 files

1.7.3.8.9

2 files

1.7.3.8.8.8

2 files

1.7.3.8.8.7

2 files

1.7.3.8.8.6

2 files

1.7.3.8.8.5

2 files

1.7.3.8.8.4

2 files

1.7.3.8.8.3

2 files

1.7.3.8.8.2

2 files

1.7.3.8.8.1

2 files

1.7.3.8.8

2 files

1.7.3.8.7.9

2 files

1.7.3.8.7.8

2 files

1.7.3.8.7.6

2 files

1.7.3.8.7.5

2 files

1.7.3.8.7.4

2 files

1.7.3.8.7.3

2 files

1.7.3.8.7.1

2 files

1.7.3.8.7

2 files

1.7.3.8.6

2 files

1.7.3.8.5

2 files

1.7.3.8.4.9

2 files

1.7.3.8.4.8

2 files

1.7.3.8.4.7

2 files

1.7.3.8.4.6

2 files

1.7.3.8.4.5

2 files

1.7.3.8.4.4

2 files

1.7.3.8.4.3

2 files

1.7.3.8.4.2

2 files

1.7.3.8.4.1

2 files

1.7.3.8.4

2 files

1.7.3.8.3

2 files

1.7.3.8.2

2 files

1.7.3.8.1

2 files

1.7.3.8

2 files

1.7.3.7.9

2 files

1.7.3.7.7

2 files

1.7.3.7.6

2 files

1.7.3.7.5

2 files

1.7.3.7.4

2 files

1.7.3.7.3

2 files

1.7.3.7.2

2 files

1.7.3.7.1

2 files

1.7.3.7

2 files

1.7.3.6.9

2 files

1.7.3.6.8

2 files

1.7.3.6.7

2 files

1.7.3.6.6

2 files

1.7.3.6.5

2 files

1.7.3.6.4

2 files

1.7.3.6.3

2 files

1.7.3.6.2

2 files

1.7.3.6.1

2 files

1.7.3.6

2 files

1.7.3.5

2 files

1.7.3.4

2 files

1.7.3.3

2 files

1.7.3.2

2 files

1.7.3

2 files

1.7.2

2 files

1.7.1.8.1

2 files

1.7.1.8

2 files

1.7.1.7

2 files

1.7.1.6

2 files

1.7.1.5

2 files

1.7.1.4

2 files

1.7.1.3

2 files

1.7.1.2

2 files

1.6.3.2

2 files

1.6.3.1

2 files

1.6.3

2 files

1.6.2

2 files

1.6.1

2 files

1.6.0

2 files

1.5.1.5

2 files

1.5.1.3

2 files

1.5.1.2

2 files

1.5.1.1

2 files

1.5.1

2 files

1.5.0.1

1 file

1.5.0

3 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