diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index e3bc9b5..e818050 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,85 +1,114 @@ +fail_fast: true repos: -- repo: https://github.com/pre-commit/pre-commit-hooks - rev: v2.3.0 - hooks: - - id: end-of-file-fixer - name: "[py - check] validate yaml" - - id: trailing-whitespace - name: "[file - format] trim trailing whitespace" - args: [ --markdown-linebreak-ext=md ] - - id: check-added-large-files + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.1.0 + hooks: + - id: end-of-file-fixer + name: "[py - check] validate yaml" + - id: trailing-whitespace + name: "[file - format] trim trailing whitespace" + args: [ --markdown-linebreak-ext=md ] + - id: check-added-large-files name: "[file - check] large file" args: [ --maxkb=5000 ] - - id: check-docstring-first + - id: check-docstring-first name: "[py - check] docstring first" files: /examples types : [file, python ] - - id: check-json + - id: check-json name: "[json - check] validate json" - - id: check-merge-conflict + - id: check-merge-conflict name: "[git - check] merge conflict" - - id: debug-statements + - id: debug-statements name: "[py - check] debug statements" - - id: detect-private-key + - id: detect-private-key name: "[cred - check] private keys" - - id: fix-encoding-pragma + - id: fix-encoding-pragma name: "[file - format] coding pragma" args: [ --remove ] - - id: mixed-line-ending + - id: mixed-line-ending name: "[file - format] mixed line ending" args: [ --fix=auto ] - - id: pretty-format-json + - id: pretty-format-json name: "[json - format] pretty json" args: [ --autofix, --indent=4, --no-sort-keys ] - - id: requirements-txt-fixer + - id: requirements-txt-fixer name: "[reqs - format] fix requirements.txt" - - id: check-yaml + - id: check-yaml name: "[yaml - check] validate yaml" -- repo: https://github.com/PyCQA/docformatter - rev: v1.4 - hooks: - - id: docformatter - name: "[py - format] docformatter" - args: [ -i, --wrap-summaries, "0" ] +# - repo: https://github.com/pre-commit/mirrors-isort +# rev: v5.10.1 +# hooks: +# - id: isort +# name: "[py - format] isort" + - repo: https://github.com/PyCQA/docformatter + rev: v1.4 + hooks: + - id: docformatter + name: "[py - format] docformatter" + args: [ -i, --wrap-summaries, "0" ] -- repo: https://github.com/PyCQA/pydocstyle - rev: 6.1.1 - hooks: - - id: pydocstyle - name: "[py - check] pydocstyle" - files: ^Hapi/ + - repo: https://github.com/PyCQA/pydocstyle + rev: 6.1.1 + hooks: + - id: pydocstyle + name: "[py - check] pydocstyle" + files: ^Hapi/ -- repo: https://gitlab.com/pycqa/flake8 - rev: 3.8.4 - hooks: - - id: flake8 - name: "[py - check] flake8" - language_version: python3.9 - exclude: ^(examples/|tests/) + - repo: https://gitlab.com/pycqa/flake8 + rev: 4.0.1 + hooks: + - id: flake8 + name: "[py - check] flake8" + language_version: python3.9 + exclude: ^(examples/|tests/) -- repo: https://github.com/psf/black - rev: 22.8.0 - hooks: - - id: black -- repo: https://github.com/pre-commit/mirrors-isort - rev: v5.7.0 - hooks: - - id: isort - name: "[py - format] isort" -- repo: https://github.com/ambv/black - rev: 22.8.0 - hooks: - - id: black - name: "[py - format] black" - language_version: python3.9 + #- repo: https://github.com/psf/black + # rev: 22.8.0 + # hooks: + # - id: black + - repo: https://github.com/ambv/black + rev: 22.8.0 + hooks: + - id: black + name: "[py - format] black" + language_version: python3.9 + - repo: https://github.com/lovesegfault/beautysh + rev: v6.2.1 + hooks: + - id: beautysh + name: "[bash - format] beautysh" -- repo: local - hooks: - - id: pytest-check - name: pytest-check - entry: pytest - language: system - pass_filenames: false - always_run: true + # pre-commit-shell: Checks shell scripts against shellcheck. + - repo: https://github.com/detailyang/pre-commit-shell + rev: v1.0.6 + hooks: + - id: shell-lint + name: "[bash - lint] shell-lint" + + - repo: https://github.com/rlindsgaard/pre-commit-commit-msg-hooks + rev: 0.1.0 + hooks: + - id: check-description-max-length + name: "[bash - format] check-description-max-length" + - id: check-second-line-empty + name: "[bash - format] check-second-line-empty" + - id: check-summary-capitalized + name: "[bash - format] check-summary-capitalized" + - id: check-summary-imperative + name: "[bash - format] check-summary-imperative" + - id: check-summary-max-length + name: "[bash - format] check-summary-max-length" + - id: check-summary-punctuation + name: "[bash - format] check-summary-punctuation" + + - repo: local + hooks: + - id: pytest-check + name: pytest-check + entry: pytest -vvv --cov=Hapi + language: system + pass_filenames: false + always_run: true diff --git a/HISTORY.rst b/HISTORY.rst index 1751ddf..1fbc66c 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -17,3 +17,10 @@ History ------------------ * bump up versions + + +0.2.0 (2023-02-08) +------------------ + +* add eva (Extreme value analysis) module +* fix bug in obtaining distribution parameters using optimization method diff --git a/README.md b/README.md index c76ec55..8df2f9f 100644 --- a/README.md +++ b/README.md @@ -14,9 +14,9 @@ Current release info ==================== -| Name | Downloads | Version | Platforms | -| --- |---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| --- | --- | -| [![Conda Recipe](https://img.shields.io/badge/recipe-statista-green.svg)](https://anaconda.org/conda-forge/statista) | [![Conda Downloads](https://img.shields.io/conda/dn/conda-forge/statista.svg)](https://anaconda.org/conda-forge/statista) [![Downloads](https://pepy.tech/badge/statista)](https://pepy.tech/project/statista) [![Downloads](https://pepy.tech/badge/statista/month)](https://pepy.tech/project/statista) [![Downloads](https://pepy.tech/badge/statista/week)](https://pepy.tech/project/statista) ![PyPI - Downloads](https://img.shields.io/pypi/dd/statista?color=blue&style=flat-square) ![GitHub all releases](https://img.shields.io/github/downloads/MAfarrag/statista/total) | [![Conda Version](https://img.shields.io/conda/vn/conda-forge/statista.svg)](https://anaconda.org/conda-forge/statista) [![PyPI version](https://badge.fury.io/py/statista.svg)](https://badge.fury.io/py/statista) [![Anaconda-Server Badge](https://anaconda.org/conda-forge/statista/badges/version.svg)](https://anaconda.org/conda-forge/statista) | [![Conda Platforms](https://img.shields.io/conda/pn/conda-forge/statista.svg)](https://anaconda.org/conda-forge/statista) [![Join the chat at https://gitter.im/Hapi-Nile/Hapi](https://badges.gitter.im/Hapi-Nile/Hapi.svg)](https://gitter.im/Hapi-Nile/Hapi?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) | +| Name | Downloads | Version | Platforms | +| --- |--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| --- | --- | +| [![Conda Recipe](https://img.shields.io/badge/recipe-statista-green.svg)](https://anaconda.org/conda-forge/statista) | [![Conda Downloads](https://img.shields.io/conda/dn/conda-forge/statista.svg)](https://anaconda.org/conda-forge/statista) [![Downloads](https://pepy.tech/badge/statista)](https://pepy.tech/project/statista) [![Downloads](https://pepy.tech/badge/statista/month)](https://pepy.tech/project/statista) [![Downloads](https://pepy.tech/badge/statista/week)](https://pepy.tech/project/statista) ![PyPI - Downloads](https://img.shields.io/pypi/dd/statista?color=blue&style=flat-square) | [![Conda Version](https://img.shields.io/conda/vn/conda-forge/statista.svg)](https://anaconda.org/conda-forge/statista) [![PyPI version](https://badge.fury.io/py/statista.svg)](https://badge.fury.io/py/statista) [![Anaconda-Server Badge](https://anaconda.org/conda-forge/statista/badges/version.svg)](https://anaconda.org/conda-forge/statista) | [![Conda Platforms](https://img.shields.io/conda/pn/conda-forge/statista.svg)](https://anaconda.org/conda-forge/statista) [![Join the chat at https://gitter.im/Hapi-Nile/Hapi](https://badges.gitter.im/Hapi-Nile/Hapi.svg)](https://gitter.im/Hapi-Nile/Hapi?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) | statista - Statistics package ===================================================================== @@ -61,7 +61,7 @@ pip install git+https://github.com/MAfarrag/statista ## pip to install the last release you can easly use pip ``` -pip install statista==0.1.8 +pip install statista==0.2.0 ``` Quick start diff --git a/poetry.lock b/poetry.lock index 8d130d0..dbf0562 100644 --- a/poetry.lock +++ b/poetry.lock @@ -706,14 +706,14 @@ files = [ [[package]] name = "mypy-extensions" -version = "0.4.3" -description = "Experimental type system extensions for programs checked with the mypy typechecker." +version = "1.0.0" +description = "Type system extensions for programs checked with the mypy type checker." category = "dev" optional = false -python-versions = "*" +python-versions = ">=3.5" files = [ - {file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"}, - {file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"}, + {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"}, + {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, ] [[package]] @@ -733,40 +733,40 @@ setuptools = "*" [[package]] name = "numpy" -version = "1.24.1" +version = "1.24.2" description = "Fundamental package for array computing in Python" category = "main" optional = false python-versions = ">=3.8" files = [ - {file = "numpy-1.24.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:179a7ef0889ab769cc03573b6217f54c8bd8e16cef80aad369e1e8185f994cd7"}, - {file = "numpy-1.24.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b09804ff570b907da323b3d762e74432fb07955701b17b08ff1b5ebaa8cfe6a9"}, - {file = "numpy-1.24.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f1b739841821968798947d3afcefd386fa56da0caf97722a5de53e07c4ccedc7"}, - {file = "numpy-1.24.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e3463e6ac25313462e04aea3fb8a0a30fb906d5d300f58b3bc2c23da6a15398"}, - {file = "numpy-1.24.1-cp310-cp310-win32.whl", hash = "sha256:b31da69ed0c18be8b77bfce48d234e55d040793cebb25398e2a7d84199fbc7e2"}, - {file = "numpy-1.24.1-cp310-cp310-win_amd64.whl", hash = "sha256:b07b40f5fb4fa034120a5796288f24c1fe0e0580bbfff99897ba6267af42def2"}, - {file = "numpy-1.24.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7094891dcf79ccc6bc2a1f30428fa5edb1e6fb955411ffff3401fb4ea93780a8"}, - {file = "numpy-1.24.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:28e418681372520c992805bb723e29d69d6b7aa411065f48216d8329d02ba032"}, - {file = "numpy-1.24.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e274f0f6c7efd0d577744f52032fdd24344f11c5ae668fe8d01aac0422611df1"}, - {file = "numpy-1.24.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0044f7d944ee882400890f9ae955220d29b33d809a038923d88e4e01d652acd9"}, - {file = "numpy-1.24.1-cp311-cp311-win32.whl", hash = "sha256:442feb5e5bada8408e8fcd43f3360b78683ff12a4444670a7d9e9824c1817d36"}, - {file = "numpy-1.24.1-cp311-cp311-win_amd64.whl", hash = "sha256:de92efa737875329b052982e37bd4371d52cabf469f83e7b8be9bb7752d67e51"}, - {file = "numpy-1.24.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b162ac10ca38850510caf8ea33f89edcb7b0bb0dfa5592d59909419986b72407"}, - {file = "numpy-1.24.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:26089487086f2648944f17adaa1a97ca6aee57f513ba5f1c0b7ebdabbe2b9954"}, - {file = "numpy-1.24.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:caf65a396c0d1f9809596be2e444e3bd4190d86d5c1ce21f5fc4be60a3bc5b36"}, - {file = "numpy-1.24.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b0677a52f5d896e84414761531947c7a330d1adc07c3a4372262f25d84af7bf7"}, - {file = "numpy-1.24.1-cp38-cp38-win32.whl", hash = "sha256:dae46bed2cb79a58d6496ff6d8da1e3b95ba09afeca2e277628171ca99b99db1"}, - {file = "numpy-1.24.1-cp38-cp38-win_amd64.whl", hash = "sha256:6ec0c021cd9fe732e5bab6401adea5a409214ca5592cd92a114f7067febcba0c"}, - {file = "numpy-1.24.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:28bc9750ae1f75264ee0f10561709b1462d450a4808cd97c013046073ae64ab6"}, - {file = "numpy-1.24.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:84e789a085aabef2f36c0515f45e459f02f570c4b4c4c108ac1179c34d475ed7"}, - {file = "numpy-1.24.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e669fbdcdd1e945691079c2cae335f3e3a56554e06bbd45d7609a6cf568c700"}, - {file = "numpy-1.24.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ef85cf1f693c88c1fd229ccd1055570cb41cdf4875873b7728b6301f12cd05bf"}, - {file = "numpy-1.24.1-cp39-cp39-win32.whl", hash = "sha256:87a118968fba001b248aac90e502c0b13606721b1343cdaddbc6e552e8dfb56f"}, - {file = "numpy-1.24.1-cp39-cp39-win_amd64.whl", hash = "sha256:ddc7ab52b322eb1e40521eb422c4e0a20716c271a306860979d450decbb51b8e"}, - {file = "numpy-1.24.1-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:ed5fb71d79e771ec930566fae9c02626b939e37271ec285e9efaf1b5d4370e7d"}, - {file = "numpy-1.24.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad2925567f43643f51255220424c23d204024ed428afc5aad0f86f3ffc080086"}, - {file = "numpy-1.24.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:cfa1161c6ac8f92dea03d625c2d0c05e084668f4a06568b77a25a89111621566"}, - {file = "numpy-1.24.1.tar.gz", hash = "sha256:2386da9a471cc00a1f47845e27d916d5ec5346ae9696e01a8a34760858fe9dd2"}, + {file = "numpy-1.24.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:eef70b4fc1e872ebddc38cddacc87c19a3709c0e3e5d20bf3954c147b1dd941d"}, + {file = "numpy-1.24.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e8d2859428712785e8a8b7d2b3ef0a1d1565892367b32f915c4a4df44d0e64f5"}, + {file = "numpy-1.24.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6524630f71631be2dabe0c541e7675db82651eb998496bbe16bc4f77f0772253"}, + {file = "numpy-1.24.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a51725a815a6188c662fb66fb32077709a9ca38053f0274640293a14fdd22978"}, + {file = "numpy-1.24.2-cp310-cp310-win32.whl", hash = "sha256:2620e8592136e073bd12ee4536149380695fbe9ebeae845b81237f986479ffc9"}, + {file = "numpy-1.24.2-cp310-cp310-win_amd64.whl", hash = "sha256:97cf27e51fa078078c649a51d7ade3c92d9e709ba2bfb97493007103c741f1d0"}, + {file = "numpy-1.24.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7de8fdde0003f4294655aa5d5f0a89c26b9f22c0a58790c38fae1ed392d44a5a"}, + {file = "numpy-1.24.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4173bde9fa2a005c2c6e2ea8ac1618e2ed2c1c6ec8a7657237854d42094123a0"}, + {file = "numpy-1.24.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4cecaed30dc14123020f77b03601559fff3e6cd0c048f8b5289f4eeabb0eb281"}, + {file = "numpy-1.24.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9a23f8440561a633204a67fb44617ce2a299beecf3295f0d13c495518908e910"}, + {file = "numpy-1.24.2-cp311-cp311-win32.whl", hash = "sha256:e428c4fbfa085f947b536706a2fc349245d7baa8334f0c5723c56a10595f9b95"}, + {file = "numpy-1.24.2-cp311-cp311-win_amd64.whl", hash = "sha256:557d42778a6869c2162deb40ad82612645e21d79e11c1dc62c6e82a2220ffb04"}, + {file = "numpy-1.24.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d0a2db9d20117bf523dde15858398e7c0858aadca7c0f088ac0d6edd360e9ad2"}, + {file = "numpy-1.24.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:c72a6b2f4af1adfe193f7beb91ddf708ff867a3f977ef2ec53c0ffb8283ab9f5"}, + {file = "numpy-1.24.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c29e6bd0ec49a44d7690ecb623a8eac5ab8a923bce0bea6293953992edf3a76a"}, + {file = "numpy-1.24.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2eabd64ddb96a1239791da78fa5f4e1693ae2dadc82a76bc76a14cbb2b966e96"}, + {file = "numpy-1.24.2-cp38-cp38-win32.whl", hash = "sha256:e3ab5d32784e843fc0dd3ab6dcafc67ef806e6b6828dc6af2f689be0eb4d781d"}, + {file = "numpy-1.24.2-cp38-cp38-win_amd64.whl", hash = "sha256:76807b4063f0002c8532cfeac47a3068a69561e9c8715efdad3c642eb27c0756"}, + {file = "numpy-1.24.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4199e7cfc307a778f72d293372736223e39ec9ac096ff0a2e64853b866a8e18a"}, + {file = "numpy-1.24.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:adbdce121896fd3a17a77ab0b0b5eedf05a9834a18699db6829a64e1dfccca7f"}, + {file = "numpy-1.24.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:889b2cc88b837d86eda1b17008ebeb679d82875022200c6e8e4ce6cf549b7acb"}, + {file = "numpy-1.24.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f64bb98ac59b3ea3bf74b02f13836eb2e24e48e0ab0145bbda646295769bd780"}, + {file = "numpy-1.24.2-cp39-cp39-win32.whl", hash = "sha256:63e45511ee4d9d976637d11e6c9864eae50e12dc9598f531c035265991910468"}, + {file = "numpy-1.24.2-cp39-cp39-win_amd64.whl", hash = "sha256:a77d3e1163a7770164404607b7ba3967fb49b24782a6ef85d9b5f54126cc39e5"}, + {file = "numpy-1.24.2-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:92011118955724465fb6853def593cf397b4a1367495e0b59a7e69d40c4eb71d"}, + {file = "numpy-1.24.2-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f9006288bcf4895917d02583cf3411f98631275bc67cce355a7f39f8c14338fa"}, + {file = "numpy-1.24.2-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:150947adbdfeceec4e5926d956a06865c1c690f2fd902efede4ca6fe2e657c3f"}, + {file = "numpy-1.24.2.tar.gz", hash = "sha256:003a9f530e880cb2cd177cba1af7220b9aa42def9c4afc2a2fc3ee6be7eb2b22"}, ] [[package]] @@ -948,19 +948,19 @@ tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "pa [[package]] name = "platformdirs" -version = "2.6.2" +version = "3.0.0" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "platformdirs-2.6.2-py3-none-any.whl", hash = "sha256:83c8f6d04389165de7c9b6f0c682439697887bca0aa2f1c87ef1826be3584490"}, - {file = "platformdirs-2.6.2.tar.gz", hash = "sha256:e1fea1fe471b9ff8332e229df3cb7de4f53eeea4998d3b6bfff542115e998bd2"}, + {file = "platformdirs-3.0.0-py3-none-any.whl", hash = "sha256:b1d5eb14f221506f50d6604a561f4c5786d9e80355219694a1b244bcd96f4567"}, + {file = "platformdirs-3.0.0.tar.gz", hash = "sha256:8a1228abb1ef82d788f74139988b137e78692984ec7b08eaa6c65f1723af28f9"}, ] [package.extras] -docs = ["furo (>=2022.12.7)", "proselint (>=0.13)", "sphinx (>=5.3)", "sphinx-autodoc-typehints (>=1.19.5)"] -test = ["appdirs (==1.4.4)", "covdefaults (>=2.2.2)", "pytest (>=7.2)", "pytest-cov (>=4)", "pytest-mock (>=3.10)"] +docs = ["furo (>=2022.12.7)", "proselint (>=0.13)", "sphinx (>=6.1.3)", "sphinx-autodoc-typehints (>=1.22,!=1.23.4)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.2.2)", "pytest (>=7.2.1)", "pytest-cov (>=4)", "pytest-mock (>=3.10)"] [[package]] name = "pluggy" @@ -980,14 +980,14 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "pre-commit" -version = "3.0.2" +version = "3.0.4" description = "A framework for managing and maintaining multi-language pre-commit hooks." category = "dev" optional = false python-versions = ">=3.8" files = [ - {file = "pre_commit-3.0.2-py2.py3-none-any.whl", hash = "sha256:f448d5224c70e196a6c6f87961d2333dfdc49988ebbf660477f9efe991c03597"}, - {file = "pre_commit-3.0.2.tar.gz", hash = "sha256:aa97fa71e7ab48225538e1e91a6b26e483029e6de64824f04760c32557bc91d7"}, + {file = "pre_commit-3.0.4-py2.py3-none-any.whl", hash = "sha256:9e3255edb0c9e7fe9b4f328cb3dc86069f8fdc38026f1bf521018a05eaf4d67b"}, + {file = "pre_commit-3.0.4.tar.gz", hash = "sha256:bc4687478d55578c4ac37272fe96df66f73d9b5cf81be6f28627d4e712e752d5"}, ] [package.dependencies] @@ -1380,14 +1380,14 @@ test = ["asv", "gmpy2", "mpmath", "pytest", "pytest-cov", "pytest-xdist", "sciki [[package]] name = "setuptools" -version = "67.0.0" +version = "67.2.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "setuptools-67.0.0-py3-none-any.whl", hash = "sha256:9d790961ba6219e9ff7d9557622d2fe136816a264dd01d5997cfc057d804853d"}, - {file = "setuptools-67.0.0.tar.gz", hash = "sha256:883131c5b6efa70b9101c7ef30b2b7b780a4283d5fc1616383cdf22c83cbefe6"}, + {file = "setuptools-67.2.0-py3-none-any.whl", hash = "sha256:16ccf598aab3b506593c17378473978908a2734d7336755a8769b480906bec1c"}, + {file = "setuptools-67.2.0.tar.gz", hash = "sha256:b440ee5f7e607bb8c9de15259dba2583dd41a38879a7abc1d43a71c59524da48"}, ] [package.extras] @@ -1484,24 +1484,24 @@ files = [ [[package]] name = "virtualenv" -version = "20.17.1" +version = "20.19.0" description = "Virtual Python Environment builder" category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" files = [ - {file = "virtualenv-20.17.1-py3-none-any.whl", hash = "sha256:ce3b1684d6e1a20a3e5ed36795a97dfc6af29bc3970ca8dab93e11ac6094b3c4"}, - {file = "virtualenv-20.17.1.tar.gz", hash = "sha256:f8b927684efc6f1cc206c9db297a570ab9ad0e51c16fa9e45487d36d1905c058"}, + {file = "virtualenv-20.19.0-py3-none-any.whl", hash = "sha256:54eb59e7352b573aa04d53f80fc9736ed0ad5143af445a1e539aada6eb947dd1"}, + {file = "virtualenv-20.19.0.tar.gz", hash = "sha256:37a640ba82ed40b226599c522d411e4be5edb339a0c0de030c0dc7b646d61590"}, ] [package.dependencies] distlib = ">=0.3.6,<1" filelock = ">=3.4.1,<4" -platformdirs = ">=2.4,<3" +platformdirs = ">=2.4,<4" [package.extras] -docs = ["proselint (>=0.13)", "sphinx (>=5.3)", "sphinx-argparse (>=0.3.2)", "sphinx-rtd-theme (>=1)", "towncrier (>=22.8)"] -testing = ["coverage (>=6.2)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=21.3)", "pytest (>=7.0.1)", "pytest-env (>=0.6.2)", "pytest-freezegun (>=0.4.2)", "pytest-mock (>=3.6.1)", "pytest-randomly (>=3.10.3)", "pytest-timeout (>=2.1)"] +docs = ["furo (>=2022.12.7)", "proselint (>=0.13)", "sphinx (>=6.1.3)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=22.12)"] +test = ["covdefaults (>=2.2.2)", "coverage (>=7.1)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23)", "pytest (>=7.2.1)", "pytest-env (>=0.8.1)", "pytest-freezegun (>=0.4.2)", "pytest-mock (>=3.10)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)"] [[package]] name = "win32-setctime" diff --git a/pyproject.toml b/pyproject.toml index f8d4f1d..ebe868d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "statista" -version = "0.1.8" +version = "0.2.0" description = "statistics package" authors = ["Mostafa Farrag "] readme = "README.md" @@ -61,7 +61,7 @@ source = ["statista"] [tool.coverage.report] show_missing = true -fail_under = 40 +fail_under = 0 [tool.isort] diff --git a/statista/distributions.py b/statista/distributions.py index 41abc5a..287b12c 100644 --- a/statista/distributions.py +++ b/statista/distributions.py @@ -328,7 +328,7 @@ def estimateParameter( elif method == "optimization": if ObjFunc is None or threshold is None: raise TypeError("threshold should be numeric value") - Param = gumbel_r.fit(self.data, method=method) + Param = gumbel_r.fit(self.data, method="mle") # then we use the result as starting value for your truncated Gumbel fit Param = so.fmin( ObjFunc, @@ -857,7 +857,7 @@ def estimateParameter( if ObjFunc is None or threshold is None: raise TypeError("ObjFunc and threshold should be numeric value") - Param = genextreme.fit(self.data, method=method) + Param = genextreme.fit(self.data, method="mle") # then we use the result as starting value for your truncated Gumbel fit Param = so.fmin( ObjFunc, diff --git a/statista/eva.py b/statista/eva.py new file mode 100644 index 0000000..00ea3f1 --- /dev/null +++ b/statista/eva.py @@ -0,0 +1,243 @@ +"""Extreme value analysis.""" +import os +from typing import Union + +import matplotlib.pyplot as plt +import numpy as np +import pandas as pd +from loguru import logger +from pandas import DataFrame + +from statista.distributions import GEV, Gumbel, PlottingPosition + + +def ams_analysis( + time_series_df: DataFrame, + ams_start: str = "A-OCT", + save_plots: bool = False, + save_to: str = None, + filter_out: Union[bool, float, int] = False, + distribution: str = "GEV", + method: str = "lmoments", + estimate_parameters: bool = False, + quartile: float = 0, + significance_level: float = 0.1, +): + """StatisticalProperties. + + ams analysis method reads resamples all the the time series in the given dataframe to annual maximum, then fits + the time series to a given distribution and parameter estimation method. + + Parameters + ---------- + time_series_df : [DataFrame] + DataFrame containing multiple time series to do the statistical analysis on. + ams_start: [str] + The beginning of the year which is used to resample the time series to get the annual maximum series. + Default is"A-OCT". + save_plots : [Bool] + True if you want to save the plots. + save_to : [str] + The rdir where you want to save the statistical properties. + filter_out: [Bool] + For observed or hydraulic model data it has gaps of times where the + model did not run or gaps in the observed data if these gap days + are filled with a specific value and you want to ignore it here + give filter_out = Value you want + distribution: [str] + Default is "GEV". + method: [str] + available methods are 'mle', 'mm', 'lmoments', optimization. Default is "lmoments" + estimate_parameters: [bool] + Default is False. + quartile: [float] + Default is 0. + significance_level: + Default is [0.1]. + + Returns + ------- + Statistical Properties.csv: + file containing some statistical properties like mean, std, min, 5%, 25%, + median, 75%, 95%, max, t_beg, t_end, nyr, q1.5, q2, q5, q10, q25, q50, + q100, q200, q500. + """ + gauges = time_series_df.columns.tolist() + # List of the table output, including some general data and the return periods. + col_csv = [ + "mean", + "std", + "min", + "5%", + "25%", + "median", + "75%", + "95%", + "max", + "t_beg", + "t_end", + "nyr", + ] + rp_name = [ + "q1.5", + "q2", + "q5", + "q10", + "q25", + "q50", + "q100", + "q200", + "q500", + "q1000", + ] + col_csv = col_csv + rp_name + + # In a table where duplicates are removed (np.unique), find the number of + # gauges contained in the .csv file. + # Declare a dataframe for the output file, with as index the gaugne numbers + # and as columns all the output names. + statistical_properties = pd.DataFrame(np.nan, index=gauges, columns=col_csv) + statistical_properties.index.name = "id" + if distribution == "GEV": + distribution_properties = pd.DataFrame( + np.nan, + index=gauges, + columns=["c", "loc", "scale", "D-static", "P-Value"], + ) + else: + distribution_properties = pd.DataFrame( + np.nan, + index=gauges, + columns=["loc", "scale", "D-static", "P-Value"], + ) + distribution_properties.index.name = "id" + # required return periods + T = [1.5, 2, 5, 10, 25, 50, 50, 100, 200, 500, 1000] + T = np.array(T) + # these values are the Non Exceedance probability (F) of the chosen + # return periods F = 1 - (1/T) + # Non Exceedance propabilities + # F = [1/3, 0.5, 0.8, 0.9, 0.96, 0.98, 0.99, 0.995, 0.998] + F = 1 - (1 / T) + # Iteration over all the gauge numbers. + if save_plots: + rpath = os.path.join(save_to, "figures") + if not os.path.exists(rpath): + os.mkdir(rpath) + + for i in gauges: + QTS = time_series_df.loc[:, i] + # The time series is resampled to the annual maxima, and turned into a + # numpy array. + # The hydrological year is 1-Nov/31-Oct (from Petrow and Merz, 2009, JoH). + ams = QTS.resample(ams_start).max().values + + if not isinstance(filter_out, bool): + ams = ams[ams != filter_out] + + if estimate_parameters: + # TODO: still to be tested and prepared for GEV + # estimate the parameters through an optimization + # alpha = (np.sqrt(6) / np.pi) * ams.std() + # beta = ams.mean() - 0.5772 * alpha + # param_dist = [beta, alpha] + threshold = np.quantile(ams, quartile) + if distribution == "GEV": + dist = GEV(ams) + param_dist = dist.estimateParameter( + method="optimization", + ObjFunc=Gumbel.ObjectiveFn, + threshold=threshold, + ) + else: + dist = Gumbel(ams) + param_dist = dist.estimateParameter( + method="optimization", + ObjFunc=Gumbel.ObjectiveFn, + threshold=threshold, + ) + else: + # estimate the parameters through an maximum liklehood method + if distribution == "GEV": + dist = GEV(ams) + # defult parameter estimation method is maximum liklihood method + param_dist = dist.estimateParameter(method=method) + else: + # A gumbel distribution is fitted to the annual maxima + dist = Gumbel(ams) + # defult parameter estimation method is maximum liklihood method + param_dist = dist.estimateParameter(method=method) + + ( + distribution_properties.loc[i, "D-static"], + distribution_properties.loc[i, "P-Value"], + ) = dist.ks() + if distribution == "GEV": + distribution_properties.loc[i, "c"] = param_dist[0] + distribution_properties.loc[i, "loc"] = param_dist[1] + distribution_properties.loc[i, "scale"] = param_dist[2] + else: + distribution_properties.loc[i, "loc"] = param_dist[0] + distribution_properties.loc[i, "scale"] = param_dist[1] + + # Return periods from the fitted distribution are stored. + # get the Discharge coresponding to the return periods + if distribution == "GEV": + Qrp = dist.theporeticalEstimate( + param_dist[0], param_dist[1], param_dist[2], F + ) + else: + Qrp = dist.theporeticalEstimate(param_dist[0], param_dist[1], F) + + # to get the Non Exceedance probability for a specific Value + # sort the ams + ams.sort() + # calculate the F (Exceedence probability based on weibul) + cdf_Weibul = PlottingPosition.weibul(ams) + # Gumbel.probapilityPlot method calculates the theoretical values + # based on the Gumbel distribution + # parameters, theoretical cdf (or weibul), and calculate the confidence interval + if save_plots: + if distribution == "GEV": + fig, ax = dist.probapilityPlot( + param_dist[0], + param_dist[1], + param_dist[2], + cdf_Weibul, + alpha=significance_level, + ) + else: + fig, ax = dist.probapilityPlot( + param_dist[0], + param_dist[1], + cdf_Weibul, + alpha=significance_level, + ) + + fig[0].savefig(f"{save_to}/figures/{i}.png", format="png") + plt.close() + + fig[1].savefig(f"{save_to}/figures/f-{i}.png", format="png") + plt.close() + + statistical_properties.loc[i, "mean"] = QTS.mean() + statistical_properties.loc[i, "std"] = QTS.std() + statistical_properties.loc[i, "min"] = QTS.min() + statistical_properties.loc[i, "5%"] = QTS.quantile(0.05) + statistical_properties.loc[i, "25%"] = QTS.quantile(0.25) + statistical_properties.loc[i, "median"] = QTS.quantile(0.50) + statistical_properties.loc[i, "75%"] = QTS.quantile(0.75) + statistical_properties.loc[i, "95%"] = QTS.quantile(0.95) + statistical_properties.loc[i, "max"] = QTS.max() + statistical_properties.loc[i, "t_beg"] = QTS.index.min() + statistical_properties.loc[i, "t_end"] = QTS.index.max() + statistical_properties.loc[i, "nyr"] = ( + statistical_properties.loc[i, "t_end"] + - statistical_properties.loc[i, "t_beg"] + ).days / 365.25 + for irp, irp_name in zip(Qrp, rp_name): + statistical_properties.loc[i, irp_name] = irp + + # Print for prompt and check progress. + logger.info(f"Gauge {i} done.") + return statistical_properties, distribution_properties