statsframe


Namestatsframe JSON
Version 0.0.3 PyPI version JSON
download
home_pagehttps://github.com/NKeleher/statsframe#readme
SummaryCustomizable data and model summaries in Python.
upload_time2024-01-31 16:25:06
maintainer
docs_urlNone
authorNiall Keleher
requires_python>=3.9,<3.13
licenseMIT
keywords tables statistics econometrics
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # statsframe

![PyPI - Version](https://img.shields.io/pypi/v/statsframe.svg) ![PyPI - Python Version](https://img.shields.io/pypi/pyversions/statsframe)
[![License](https://img.shields.io/github/license/NKeleher/statsframe)](https://img.shields.io/github/license/NKeleher/statsframe)
[![Repo Status](https://www.repostatus.org/badges/latest/active.svg)](https://www.repostatus.org/#active)

---

**Customizable data and model summaries in Python.**

`statsframe` creates tables that provide descriptive statistics of
numeric and categorical data.

The goal is to provide a simple -- yet customizable -- way to summarize
data and models in Python.

`statsframe` is heavily inspired by [`modelsummary`](https://modelsummary.com/)
in R. The goal is not to replicate all that `modelsummary` does, but to provide
a way of achieving similar results in Python.

In order to achieve this, `statsframe` builds on the [`polars`](https://docs.pola.rs/)
library to produce tables that can be easily customized and exported to other formats.

## Basic Usage

As an example of `statsframe` usage, the `skim_frame` function provides a
summary of a DataFrame (either `polars.DataFrame` or `pandas.DataFrame`).
The default summary statistics returned by `statsframe.skim_frame()` are unique values,
percentage missing, mean, standard deviation, minimum, median, and maximum.

Where possible, `statsframe` will print a table to the console and return a
polars DataFrame with the summary statistics. This allows for easy customization.
For example, the `polars.DataFrame` with statistics from `statsframe` can be
modified using the
[`Great Tables`](https://posit-dev.github.io/great-tables/reference/) package.

```python
import polars as pl
import statsframe as sf

df = (
        pl.read_csv("https://vincentarelbundock.github.io/Rdatasets/csv/datasets/mtcars.csv")
          .drop("rownames")
    )

stats = sf.skim_frame(df)

Summary Statistics
Rows: 32, Columns: 11
┌──────┬────────────┬─────────────┬───────┬───────┬──────┬────────┬───────┐
│      ┆ Unique (#) ┆ Missing (%) ┆  Mean ┆    SD ┆  Min ┆ Median ┆   Max │
╞══════╪════════════╪═════════════╪═══════╪═══════╪══════╪════════╪═══════╡
│  mpg ┆         25 ┆         0.0 ┆  20.1 ┆   6.0 ┆ 10.4 ┆   19.2 ┆  33.9 │
│  cyl ┆          3 ┆         0.0 ┆   6.2 ┆   1.8 ┆  4.0 ┆    6.0 ┆   8.0 │
│ disp ┆         27 ┆         0.0 ┆ 230.7 ┆ 123.9 ┆ 71.1 ┆  196.3 ┆ 472.0 │
│   hp ┆         22 ┆         0.0 ┆ 146.7 ┆  68.6 ┆ 52.0 ┆  123.0 ┆ 335.0 │
│ drat ┆         22 ┆         0.0 ┆   3.6 ┆   0.5 ┆  2.8 ┆    3.7 ┆   4.9 │
│   wt ┆         29 ┆         0.0 ┆   3.2 ┆   1.0 ┆  1.5 ┆    3.3 ┆   5.4 │
│ qsec ┆         30 ┆         0.0 ┆  17.8 ┆   1.8 ┆ 14.5 ┆   17.7 ┆  22.9 │
│   vs ┆          2 ┆         0.0 ┆   0.4 ┆   0.5 ┆  0.0 ┆    0.0 ┆   1.0 │
│   am ┆          2 ┆         0.0 ┆   0.4 ┆   0.5 ┆  0.0 ┆    0.0 ┆   1.0 │
│ gear ┆          3 ┆         0.0 ┆   3.7 ┆   0.7 ┆  3.0 ┆    4.0 ┆   5.0 │
│ carb ┆          6 ┆         0.0 ┆   2.8 ┆   1.6 ┆  1.0 ┆    2.0 ┆   8.0 │
└──────┴────────────┴─────────────┴───────┴───────┴──────┴────────┴───────┘
```

We can achieve the same result above with a pandas DataFrame.

```python
import pandas as pd
import statsframe as sf

trees_df = pd.read_csv(
    "https://vincentarelbundock.github.io/Rdatasets/csv/datasets/trees.csv"
).drop(columns=["rownames"])

trees_stats = sf.skim_frame(trees_df)

Summary Statistics
Rows: 31, Columns: 3
┌────────┬────────────┬─────────────┬──────┬──────┬──────┬────────┬──────┐
│        ┆ Unique (#) ┆ Missing (%) ┆ Mean ┆   SD ┆  Min ┆ Median ┆  Max │
╞════════╪════════════╪═════════════╪══════╪══════╪══════╪════════╪══════╡
│  Girth ┆         27 ┆         0.0 ┆ 13.2 ┆  3.1 ┆  8.3 ┆   12.9 ┆ 20.6 │
│ Height ┆         21 ┆         0.0 ┆ 76.0 ┆  6.4 ┆ 63.0 ┆   76.0 ┆ 87.0 │
│ Volume ┆         30 ┆         0.0 ┆ 30.2 ┆ 16.4 ┆ 10.2 ┆   24.2 ┆ 77.0 │
└────────┴────────────┴─────────────┴──────┴──────┴──────┴────────┴──────┘

```

## Contributing

If you encounter a bug, have usage questions, or want to share ideas to make
the `statsframe` package more useful, please feel free to file an
[issue](https://github.com/NKeleher/statsframe/issues).

## Code of Conduct

Please note that the **statsframe** project is released with a
[contributor code of conduct](https://www.contributor-covenant.org/version/2/1/code_of_conduct/).

By participating in this project you agree to abide by its terms.

## License

**statsframe** is licensed under the MIT license.

## Governance

This project is primarily maintained by [Niall Keleher](https://twitter.com/nkeleher).
Contributions from other authors is welcome.

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/NKeleher/statsframe#readme",
    "name": "statsframe",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.9,<3.13",
    "maintainer_email": "",
    "keywords": "tables,statistics,econometrics",
    "author": "Niall Keleher",
    "author_email": "niall.keleher@gmail.com",
    "download_url": "https://files.pythonhosted.org/packages/75/da/e8cc6588b05b3e882f30fdb4bbadfe6516da37a619e0a9b2e3f507e8191f/statsframe-0.0.3.tar.gz",
    "platform": null,
    "description": "# statsframe\n\n![PyPI - Version](https://img.shields.io/pypi/v/statsframe.svg) ![PyPI - Python Version](https://img.shields.io/pypi/pyversions/statsframe)\n[![License](https://img.shields.io/github/license/NKeleher/statsframe)](https://img.shields.io/github/license/NKeleher/statsframe)\n[![Repo Status](https://www.repostatus.org/badges/latest/active.svg)](https://www.repostatus.org/#active)\n\n---\n\n**Customizable data and model summaries in Python.**\n\n`statsframe` creates tables that provide descriptive statistics of\nnumeric and categorical data.\n\nThe goal is to provide a simple -- yet customizable -- way to summarize\ndata and models in Python.\n\n`statsframe` is heavily inspired by [`modelsummary`](https://modelsummary.com/)\nin R. The goal is not to replicate all that `modelsummary` does, but to provide\na way of achieving similar results in Python.\n\nIn order to achieve this, `statsframe` builds on the [`polars`](https://docs.pola.rs/)\nlibrary to produce tables that can be easily customized and exported to other formats.\n\n## Basic Usage\n\nAs an example of `statsframe` usage, the `skim_frame` function provides a\nsummary of a DataFrame (either `polars.DataFrame` or `pandas.DataFrame`).\nThe default summary statistics returned by `statsframe.skim_frame()` are unique values,\npercentage missing, mean, standard deviation, minimum, median, and maximum.\n\nWhere possible, `statsframe` will print a table to the console and return a\npolars DataFrame with the summary statistics. This allows for easy customization.\nFor example, the `polars.DataFrame` with statistics from `statsframe` can be\nmodified using the\n[`Great Tables`](https://posit-dev.github.io/great-tables/reference/) package.\n\n```python\nimport polars as pl\nimport statsframe as sf\n\ndf = (\n        pl.read_csv(\"https://vincentarelbundock.github.io/Rdatasets/csv/datasets/mtcars.csv\")\n          .drop(\"rownames\")\n    )\n\nstats = sf.skim_frame(df)\n\nSummary Statistics\nRows: 32, Columns: 11\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502      \u2506 Unique (#) \u2506 Missing (%) \u2506  Mean \u2506    SD \u2506  Min \u2506 Median \u2506   Max \u2502\n\u255e\u2550\u2550\u2550\u2550\u2550\u2550\u256a\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u256a\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u256a\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u256a\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u256a\u2550\u2550\u2550\u2550\u2550\u2550\u256a\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u256a\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2561\n\u2502  mpg \u2506         25 \u2506         0.0 \u2506  20.1 \u2506   6.0 \u2506 10.4 \u2506   19.2 \u2506  33.9 \u2502\n\u2502  cyl \u2506          3 \u2506         0.0 \u2506   6.2 \u2506   1.8 \u2506  4.0 \u2506    6.0 \u2506   8.0 \u2502\n\u2502 disp \u2506         27 \u2506         0.0 \u2506 230.7 \u2506 123.9 \u2506 71.1 \u2506  196.3 \u2506 472.0 \u2502\n\u2502   hp \u2506         22 \u2506         0.0 \u2506 146.7 \u2506  68.6 \u2506 52.0 \u2506  123.0 \u2506 335.0 \u2502\n\u2502 drat \u2506         22 \u2506         0.0 \u2506   3.6 \u2506   0.5 \u2506  2.8 \u2506    3.7 \u2506   4.9 \u2502\n\u2502   wt \u2506         29 \u2506         0.0 \u2506   3.2 \u2506   1.0 \u2506  1.5 \u2506    3.3 \u2506   5.4 \u2502\n\u2502 qsec \u2506         30 \u2506         0.0 \u2506  17.8 \u2506   1.8 \u2506 14.5 \u2506   17.7 \u2506  22.9 \u2502\n\u2502   vs \u2506          2 \u2506         0.0 \u2506   0.4 \u2506   0.5 \u2506  0.0 \u2506    0.0 \u2506   1.0 \u2502\n\u2502   am \u2506          2 \u2506         0.0 \u2506   0.4 \u2506   0.5 \u2506  0.0 \u2506    0.0 \u2506   1.0 \u2502\n\u2502 gear \u2506          3 \u2506         0.0 \u2506   3.7 \u2506   0.7 \u2506  3.0 \u2506    4.0 \u2506   5.0 \u2502\n\u2502 carb \u2506          6 \u2506         0.0 \u2506   2.8 \u2506   1.6 \u2506  1.0 \u2506    2.0 \u2506   8.0 \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n```\n\nWe can achieve the same result above with a pandas DataFrame.\n\n```python\nimport pandas as pd\nimport statsframe as sf\n\ntrees_df = pd.read_csv(\n    \"https://vincentarelbundock.github.io/Rdatasets/csv/datasets/trees.csv\"\n).drop(columns=[\"rownames\"])\n\ntrees_stats = sf.skim_frame(trees_df)\n\nSummary Statistics\nRows: 31, Columns: 3\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502        \u2506 Unique (#) \u2506 Missing (%) \u2506 Mean \u2506   SD \u2506  Min \u2506 Median \u2506  Max \u2502\n\u255e\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u256a\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u256a\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u256a\u2550\u2550\u2550\u2550\u2550\u2550\u256a\u2550\u2550\u2550\u2550\u2550\u2550\u256a\u2550\u2550\u2550\u2550\u2550\u2550\u256a\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u256a\u2550\u2550\u2550\u2550\u2550\u2550\u2561\n\u2502  Girth \u2506         27 \u2506         0.0 \u2506 13.2 \u2506  3.1 \u2506  8.3 \u2506   12.9 \u2506 20.6 \u2502\n\u2502 Height \u2506         21 \u2506         0.0 \u2506 76.0 \u2506  6.4 \u2506 63.0 \u2506   76.0 \u2506 87.0 \u2502\n\u2502 Volume \u2506         30 \u2506         0.0 \u2506 30.2 \u2506 16.4 \u2506 10.2 \u2506   24.2 \u2506 77.0 \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n\n```\n\n## Contributing\n\nIf you encounter a bug, have usage questions, or want to share ideas to make\nthe `statsframe` package more useful, please feel free to file an\n[issue](https://github.com/NKeleher/statsframe/issues).\n\n## Code of Conduct\n\nPlease note that the **statsframe** project is released with a\n[contributor code of conduct](https://www.contributor-covenant.org/version/2/1/code_of_conduct/).\n\nBy participating in this project you agree to abide by its terms.\n\n## License\n\n**statsframe** is licensed under the MIT license.\n\n## Governance\n\nThis project is primarily maintained by [Niall Keleher](https://twitter.com/nkeleher).\nContributions from other authors is welcome.\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "Customizable data and model summaries in Python.",
    "version": "0.0.3",
    "project_urls": {
        "Homepage": "https://github.com/NKeleher/statsframe#readme",
        "Repository": "https://github.com/NKeleher/statsframe"
    },
    "split_keywords": [
        "tables",
        "statistics",
        "econometrics"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "6eafc125a57702b976eb2419d9d2f3427c92c50667ddbe737a5965be6f437bd7",
                "md5": "022d21d3d16f243ce4f22066fa791877",
                "sha256": "d46d2c25c38d71de44d842402e98db762f9f6a70f4b1ebd09ca07511ff535991"
            },
            "downloads": -1,
            "filename": "statsframe-0.0.3-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "022d21d3d16f243ce4f22066fa791877",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.9,<3.13",
            "size": 12800,
            "upload_time": "2024-01-31T16:25:04",
            "upload_time_iso_8601": "2024-01-31T16:25:04.204041Z",
            "url": "https://files.pythonhosted.org/packages/6e/af/c125a57702b976eb2419d9d2f3427c92c50667ddbe737a5965be6f437bd7/statsframe-0.0.3-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "75dae8cc6588b05b3e882f30fdb4bbadfe6516da37a619e0a9b2e3f507e8191f",
                "md5": "bbd2dc0a2883461e9cdcf023c93eee59",
                "sha256": "67ae47ca693990100065341c9aeb0b6c5fe2c8e302b47fc3ddee6336d5b548d1"
            },
            "downloads": -1,
            "filename": "statsframe-0.0.3.tar.gz",
            "has_sig": false,
            "md5_digest": "bbd2dc0a2883461e9cdcf023c93eee59",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.9,<3.13",
            "size": 12658,
            "upload_time": "2024-01-31T16:25:06",
            "upload_time_iso_8601": "2024-01-31T16:25:06.321507Z",
            "url": "https://files.pythonhosted.org/packages/75/da/e8cc6588b05b3e882f30fdb4bbadfe6516da37a619e0a9b2e3f507e8191f/statsframe-0.0.3.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-01-31 16:25:06",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "NKeleher",
    "github_project": "statsframe#readme",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "statsframe"
}
        
Elapsed time: 0.19095s