From 17701d0e4e91ff91d5b569225adeca44df4b214e Mon Sep 17 00:00:00 2001 From: zStupan Date: Fri, 25 Feb 2022 23:16:49 +0100 Subject: [PATCH 1/5] Update dependencies --- poetry.lock | 436 ++++++++++++++++++++++++++++--------------------- pyproject.toml | 14 +- 2 files changed, 263 insertions(+), 187 deletions(-) diff --git a/poetry.lock b/poetry.lock index 031d82e..d962c8d 100644 --- a/poetry.lock +++ b/poetry.lock @@ -8,17 +8,17 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [[package]] name = "attrs" -version = "21.2.0" +version = "21.4.0" description = "Classes Without Boilerplate" category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" [package.extras] -dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "furo", "sphinx", "sphinx-notfound-page", "pre-commit"] +dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "furo", "sphinx", "sphinx-notfound-page", "pre-commit", "cloudpickle"] docs = ["furo", "sphinx", "zope.interface", "sphinx-notfound-page"] -tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface"] -tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins"] +tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "cloudpickle"] +tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "cloudpickle"] [[package]] name = "colorama" @@ -46,14 +46,14 @@ python-versions = ">=3.6" [[package]] name = "fonttools" -version = "4.28.2" +version = "4.29.1" description = "Tools to manipulate font files" category = "main" optional = false python-versions = ">=3.7" [package.extras] -all = ["fs (>=2.2.0,<3)", "lxml (>=4.0,<5)", "zopfli (>=0.1.4)", "lz4 (>=1.7.4.2)", "matplotlib", "sympy", "skia-pathops (>=0.5.0)", "brotlicffi (>=0.8.0)", "scipy", "brotli (>=1.0.1)", "munkres", "unicodedata2 (>=13.0.0)", "xattr"] +all = ["fs (>=2.2.0,<3)", "lxml (>=4.0,<5)", "zopfli (>=0.1.4)", "lz4 (>=1.7.4.2)", "matplotlib", "sympy", "skia-pathops (>=0.5.0)", "brotlicffi (>=0.8.0)", "scipy", "brotli (>=1.0.1)", "munkres", "unicodedata2 (>=14.0.0)", "xattr"] graphite = ["lz4 (>=1.7.4.2)"] interpolatable = ["scipy", "munkres"] lxml = ["lxml (>=4.0,<5)"] @@ -62,16 +62,16 @@ plot = ["matplotlib"] symfont = ["sympy"] type1 = ["xattr"] ufo = ["fs (>=2.2.0,<3)"] -unicode = ["unicodedata2 (>=13.0.0)"] +unicode = ["unicodedata2 (>=14.0.0)"] woff = ["zopfli (>=0.1.4)", "brotlicffi (>=0.8.0)", "brotli (>=1.0.1)"] [[package]] name = "importlib-metadata" -version = "4.8.2" +version = "4.11.1" description = "Read metadata from Python packages" category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" [package.dependencies] typing-extensions = {version = ">=3.6.4", markers = "python_version < \"3.8\""} @@ -80,7 +80,7 @@ zipp = ">=0.5" [package.extras] docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"] perf = ["ipython"] -testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "packaging", "pep517", "pyfakefs", "flufl.flake8", "pytest-perf (>=0.9.2)", "pytest-black (>=0.3.7)", "pytest-mypy", "importlib-resources (>=1.3)"] +testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "packaging", "pyfakefs", "flufl.flake8", "pytest-perf (>=0.9.2)", "pytest-black (>=0.3.7)", "pytest-mypy (>=0.9.1)", "importlib-resources (>=1.3)"] [[package]] name = "iniconfig" @@ -100,7 +100,7 @@ python-versions = ">=3.7" [[package]] name = "matplotlib" -version = "3.5.0" +version = "3.5.1" description = "Python plotting package" category = "main" optional = false @@ -119,7 +119,7 @@ setuptools_scm = ">=4" [[package]] name = "niapy" -version = "2.0.0rc18" +version = "2.0.0" description = "Python micro framework for building nature-inspired algorithms." category = "main" optional = false @@ -133,11 +133,19 @@ pandas = ">=0.24.2" [[package]] name = "numpy" -version = "1.21.1" +version = "1.21.5" description = "NumPy is the fundamental package for array computing with Python." category = "main" optional = false -python-versions = ">=3.7" +python-versions = ">=3.7,<3.11" + +[[package]] +name = "numpy" +version = "1.22.2" +description = "NumPy is the fundamental package for array computing with Python." +category = "main" +optional = false +python-versions = ">=3.8" [[package]] name = "openpyxl" @@ -163,23 +171,48 @@ pyparsing = ">=2.0.2,<3.0.5 || >3.0.5" [[package]] name = "pandas" -version = "1.1.5" +version = "1.3.5" description = "Powerful data structures for data analysis, time series, and statistics" category = "main" optional = false -python-versions = ">=3.6.1" +python-versions = ">=3.7.1" [package.dependencies] -numpy = ">=1.15.4" +numpy = [ + {version = ">=1.17.3", markers = "platform_machine != \"aarch64\" and platform_machine != \"arm64\" and python_version < \"3.10\""}, + {version = ">=1.19.2", markers = "platform_machine == \"aarch64\" and python_version < \"3.10\""}, + {version = ">=1.20.0", markers = "platform_machine == \"arm64\" and python_version < \"3.10\""}, +] python-dateutil = ">=2.7.3" -pytz = ">=2017.2" +pytz = ">=2017.3" [package.extras] -test = ["pytest (>=4.0.2)", "pytest-xdist", "hypothesis (>=3.58)"] +test = ["hypothesis (>=3.58)", "pytest (>=6.0)", "pytest-xdist"] + +[[package]] +name = "pandas" +version = "1.4.1" +description = "Powerful data structures for data analysis, time series, and statistics" +category = "main" +optional = false +python-versions = ">=3.8" + +[package.dependencies] +numpy = [ + {version = ">=1.18.5", markers = "platform_machine != \"aarch64\" and platform_machine != \"arm64\" and python_version < \"3.10\""}, + {version = ">=1.19.2", markers = "platform_machine == \"aarch64\" and python_version < \"3.10\""}, + {version = ">=1.20.0", markers = "platform_machine == \"arm64\" and python_version < \"3.10\""}, + {version = ">=1.21.0", markers = "python_version >= \"3.10\""}, +] +python-dateutil = ">=2.8.1" +pytz = ">=2020.1" + +[package.extras] +test = ["hypothesis (>=5.5.3)", "pytest (>=6.0)", "pytest-xdist (>=1.31)"] [[package]] name = "pillow" -version = "9.0.0" +version = "9.0.1" description = "Python Imaging Library (Fork)" category = "main" optional = false @@ -210,7 +243,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" [[package]] name = "pyparsing" -version = "3.0.6" +version = "3.0.7" description = "Python parsing module" category = "main" optional = false @@ -221,7 +254,7 @@ diagrams = ["jinja2", "railroad-diagrams"] [[package]] name = "pytest" -version = "6.2.5" +version = "7.0.1" description = "pytest: simple powerful testing with Python" category = "dev" optional = false @@ -236,10 +269,10 @@ iniconfig = "*" packaging = "*" pluggy = ">=0.12,<2.0" py = ">=1.8.2" -toml = "*" +tomli = ">=1.0.0" [package.extras] -testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"] +testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "xmlschema"] [[package]] name = "python-dateutil" @@ -262,7 +295,7 @@ python-versions = "*" [[package]] name = "setuptools-scm" -version = "6.3.2" +version = "6.4.2" description = "the blessed package to manage your versions by scm tags" category = "main" optional = false @@ -273,7 +306,8 @@ packaging = ">=20.0" tomli = ">=1.0.0" [package.extras] -toml = ["setuptools (>=42)", "tomli (>=1.0.0)"] +test = ["pytest (>=6.2)", "virtualenv (>20)"] +toml = ["setuptools (>=42)"] [[package]] name = "six" @@ -283,25 +317,17 @@ category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" -[[package]] -name = "toml" -version = "0.10.2" -description = "Python Library for Tom's Obvious, Minimal Language" -category = "dev" -optional = false -python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" - [[package]] name = "tomli" -version = "1.2.2" +version = "2.0.1" description = "A lil' TOML parser" category = "main" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" [[package]] name = "typing-extensions" -version = "4.0.0" +version = "4.1.1" description = "Backported and Experimental Type Hints for Python 3.6+" category = "dev" optional = false @@ -309,20 +335,20 @@ python-versions = ">=3.6" [[package]] name = "zipp" -version = "3.6.0" +version = "3.7.0" description = "Backport of pathlib-compatible object wrapper for zip files" category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" [package.extras] docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"] -testing = ["pytest (>=4.6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "jaraco.itertools", "func-timeout", "pytest-black (>=0.3.7)", "pytest-mypy"] +testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "jaraco.itertools", "func-timeout", "pytest-black (>=0.3.7)", "pytest-mypy"] [metadata] lock-version = "1.1" python-versions = "^3.7" -content-hash = "5d2491588311828fe71bc4acd196838f96df70043cc39e1c24ce262e7b2c673d" +content-hash = "d4d683e5d8166ab7f852a79dcf5462ccfdf81b88cb9d07bb1ac6fa0e17611c0c" [metadata.files] atomicwrites = [ @@ -330,8 +356,8 @@ atomicwrites = [ {file = "atomicwrites-1.4.0.tar.gz", hash = "sha256:ae70396ad1a434f9c7046fd2dd196fc04b12f9e91ffb859164193be8b6168a7a"}, ] attrs = [ - {file = "attrs-21.2.0-py2.py3-none-any.whl", hash = "sha256:149e90d6d8ac20db7a955ad60cf0e6881a3f20d37096140088356da6c716b0b1"}, - {file = "attrs-21.2.0.tar.gz", hash = "sha256:ef6aaac3ca6cd92904cdd0d83f629a15f18053ec84e6432106f7a4d04ae4f5fb"}, + {file = "attrs-21.4.0-py2.py3-none-any.whl", hash = "sha256:2d27e3784d7a565d36ab851fe94887c5eccd6a463168875832a1be79c82828b4"}, + {file = "attrs-21.4.0.tar.gz", hash = "sha256:626ba8234211db98e869df76230a137c4c40a12d72445c45d5f5b716f076e2fd"}, ] colorama = [ {file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"}, @@ -346,12 +372,12 @@ et-xmlfile = [ {file = "et_xmlfile-1.1.0.tar.gz", hash = "sha256:8eb9e2bc2f8c97e37a2dc85a09ecdcdec9d8a396530a6d5a33b30b9a92da0c5c"}, ] fonttools = [ - {file = "fonttools-4.28.2-py3-none-any.whl", hash = "sha256:eff1da7ea274c54cb8842853005a139f711646cbf6f1bcfb6c9b86a627f35ff0"}, - {file = "fonttools-4.28.2.zip", hash = "sha256:dca694331af74c8ad47acc5171e57f6b78fac5692bf050f2ab572964577ac0dd"}, + {file = "fonttools-4.29.1-py3-none-any.whl", hash = "sha256:1933415e0fbdf068815cb1baaa1f159e17830215f7e8624e5731122761627557"}, + {file = "fonttools-4.29.1.zip", hash = "sha256:2b18a172120e32128a80efee04cff487d5d140fe7d817deb648b2eee023a40e4"}, ] importlib-metadata = [ - {file = "importlib_metadata-4.8.2-py3-none-any.whl", hash = "sha256:53ccfd5c134223e497627b9815d5030edf77d2ed573922f7a0b8f8bb81a1c100"}, - {file = "importlib_metadata-4.8.2.tar.gz", hash = "sha256:75bdec14c397f528724c1bfd9709d660b33a4d2e77387a3358f20b848bb5e5fb"}, + {file = "importlib_metadata-4.11.1-py3-none-any.whl", hash = "sha256:e0bc84ff355328a4adfc5240c4f211e0ab386f80aa640d1b11f0618a1d282094"}, + {file = "importlib_metadata-4.11.1.tar.gz", hash = "sha256:175f4ee440a0317f6e8d81b7f8d4869f93316170a65ad2b007d2929186c8052c"}, ] iniconfig = [ {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"}, @@ -404,75 +430,96 @@ kiwisolver = [ {file = "kiwisolver-1.3.2.tar.gz", hash = "sha256:fc4453705b81d03568d5b808ad8f09c77c47534f6ac2e72e733f9ca4714aa75c"}, ] matplotlib = [ - {file = "matplotlib-3.5.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4b018ea6f26424a0852eb60eb406420d9f0d34f65736ea7bbfbb104946a66d86"}, - {file = "matplotlib-3.5.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a07ff2565da72a7b384a9e000b15b6b8270d81370af8a3531a16f6fbcee023cc"}, - {file = "matplotlib-3.5.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2eea16883aa7724c95eea0eb473ab585c6cf66f0e28f7f13e63deb38f4fd6d0f"}, - {file = "matplotlib-3.5.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0e020a42f3338823a393dd2f80e39a2c07b9f941dfe2c778eb104eeb33d60bb5"}, - {file = "matplotlib-3.5.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9bac8eb1eccef540d7f4e844b6313d9f7722efd48c07e1b4bfec1056132127fd"}, - {file = "matplotlib-3.5.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a7cb59ebd63a8ac4542ec1c61dd08724f82ec3aa7bb6b4b9e212d43c611ce3d"}, - {file = "matplotlib-3.5.0-cp310-cp310-win32.whl", hash = "sha256:6e0e6b2111165522ad336705499b1f968c34a9e84d05d498ee5af0b5697d1efe"}, - {file = "matplotlib-3.5.0-cp310-cp310-win_amd64.whl", hash = "sha256:ff5d9fe518ad2de14ce82ab906b6ab5c2b0c7f4f984400ff8a7a905daa580a0a"}, - {file = "matplotlib-3.5.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:66b172610db0ececebebb09d146f54205f87c7b841454e408fba854764f91bdd"}, - {file = "matplotlib-3.5.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ee3d9ff16d749a9aa521bd7d86f0dbf256b2d2ac8ce31b19e4d2c86d2f2ff0b6"}, - {file = "matplotlib-3.5.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:970aa97297537540369d05fe0fd1bb952593f9ab696c9b427c06990a83e2418b"}, - {file = "matplotlib-3.5.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:153a0cf6a6ff4f406a0600d2034710c49988bacc6313d193b32716f98a697580"}, - {file = "matplotlib-3.5.0-cp37-cp37m-win32.whl", hash = "sha256:6db02c5605f063b67780f4d5753476b6a4944343284aa4e93c5e8ff6e9ec7f76"}, - {file = "matplotlib-3.5.0-cp37-cp37m-win_amd64.whl", hash = "sha256:df0042cab69f4d246f4cb8fc297770ac4ae6ec2983f61836b04a117722037dcd"}, - {file = "matplotlib-3.5.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:a7bf8b05c214d32fb7ca7c001fde70b9b426378e897b0adbf77b85ea3569d56a"}, - {file = "matplotlib-3.5.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0abf8b51cc6d3ba34d1b15b26e329f23879848a0cf1216954c1f432ffc7e1af7"}, - {file = "matplotlib-3.5.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:13930a0c9bec0fd25f43c448b047a21af1353328b946f044a8fc3be077c6b1a8"}, - {file = "matplotlib-3.5.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18f6e52386300db5cc4d1e9019ad9da2e80658bab018834d963ebb0aa5355095"}, - {file = "matplotlib-3.5.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ba107add08e12600b072cf3c47aaa1ab85dd4d3c48107a5d3377d1bf80f8b235"}, - {file = "matplotlib-3.5.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:2089b9014792dcc87bb1d620cde847913338abf7d957ef05587382b0cb76d44e"}, - {file = "matplotlib-3.5.0-cp38-cp38-win32.whl", hash = "sha256:f23fbf70d2e80f4e03a83fc1206a8306d9bc50482fee4239f10676ce7e470c83"}, - {file = "matplotlib-3.5.0-cp38-cp38-win_amd64.whl", hash = "sha256:71a1851111f23f82fc43d2b6b2bfdd3f760579a664ebc939576fe21cc6133d01"}, - {file = "matplotlib-3.5.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:d092b7ba63182d2dd427904e3eb58dd5c46ec67c5968de14a4b5007010a3a4cc"}, - {file = "matplotlib-3.5.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ac17a7e7b06ee426a4989f0b7f24ab1a592e39cdf56353a90f4e998bc0bf44d6"}, - {file = "matplotlib-3.5.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a5b62d1805cc83d755972033c05cea78a1e177a159fc84da5c9c4ab6303ccbd9"}, - {file = "matplotlib-3.5.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:666d717a4798eb9c5d3ae83fe80c7bc6ed696b93e879cb01cb24a74155c73612"}, - {file = "matplotlib-3.5.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:65f877882b7ddede7090c7d87be27a0f4720fe7fc6fddd4409c06e1aa0f1ae8d"}, - {file = "matplotlib-3.5.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:7baf23adb698d8c6ca7339c9dde00931bc47b2dd82fa912827fef9f93db77f5e"}, - {file = "matplotlib-3.5.0-cp39-cp39-win32.whl", hash = "sha256:b3b687e905da32e5f2e5f16efa713f5d1fcd9fb8b8c697895de35c91fedeb086"}, - {file = "matplotlib-3.5.0-cp39-cp39-win_amd64.whl", hash = "sha256:a6cef5b31e27c31253c0f852b629a38d550ae66ec6850129c49d872f9ee428cb"}, - {file = "matplotlib-3.5.0-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a0dcaf5648cecddc328e81a0421821a1f65a1d517b20746c94a1f0f5c36fb51a"}, - {file = "matplotlib-3.5.0-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:b5e439d9e55d645f2a4dca63e2f66d68fe974c405053b132d61c7e98c25dfeb2"}, - {file = "matplotlib-3.5.0-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:dc8c5c23e7056e126275dbf29efba817b3d94196690930d0968873ac3a94ab82"}, - {file = "matplotlib-3.5.0-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:a0ea10faa3bab0714d3a19c7e0921279a68d57552414d6eceaea99f97d7735db"}, - {file = "matplotlib-3.5.0.tar.gz", hash = "sha256:38892a254420d95594285077276162a5e9e9c30b6da08bdc2a4d53331ad9a6fa"}, + {file = "matplotlib-3.5.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:456cc8334f6d1124e8ff856b42d2cc1c84335375a16448189999496549f7182b"}, + {file = "matplotlib-3.5.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:8a77906dc2ef9b67407cec0bdbf08e3971141e535db888974a915be5e1e3efc6"}, + {file = "matplotlib-3.5.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8e70ae6475cfd0fad3816dcbf6cac536dc6f100f7474be58d59fa306e6e768a4"}, + {file = "matplotlib-3.5.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:53273c5487d1c19c3bc03b9eb82adaf8456f243b97ed79d09dded747abaf1235"}, + {file = "matplotlib-3.5.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e3b6f3fd0d8ca37861c31e9a7cab71a0ef14c639b4c95654ea1dd153158bf0df"}, + {file = "matplotlib-3.5.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e8c87cdaf06fd7b2477f68909838ff4176f105064a72ca9d24d3f2a29f73d393"}, + {file = "matplotlib-3.5.1-cp310-cp310-win32.whl", hash = "sha256:e2f28a07b4f82abb40267864ad7b3a4ed76f1b1663e81c7efc84a9b9248f672f"}, + {file = "matplotlib-3.5.1-cp310-cp310-win_amd64.whl", hash = "sha256:d70a32ee1f8b55eed3fd4e892f0286df8cccc7e0475c11d33b5d0a148f5c7599"}, + {file = "matplotlib-3.5.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:68fa30cec89b6139dc559ed6ef226c53fd80396da1919a1b5ef672c911aaa767"}, + {file = "matplotlib-3.5.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e3484d8455af3fdb0424eae1789af61f6a79da0c80079125112fd5c1b604218"}, + {file = "matplotlib-3.5.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e293b16cf303fe82995e41700d172a58a15efc5331125d08246b520843ef21ee"}, + {file = "matplotlib-3.5.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:e3520a274a0e054e919f5b3279ee5dbccf5311833819ccf3399dab7c83e90a25"}, + {file = "matplotlib-3.5.1-cp37-cp37m-win32.whl", hash = "sha256:2252bfac85cec7af4a67e494bfccf9080bcba8a0299701eab075f48847cca907"}, + {file = "matplotlib-3.5.1-cp37-cp37m-win_amd64.whl", hash = "sha256:abf67e05a1b7f86583f6ebd01f69b693b9c535276f4e943292e444855870a1b8"}, + {file = "matplotlib-3.5.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:6c094e4bfecd2fa7f9adffd03d8abceed7157c928c2976899de282f3600f0a3d"}, + {file = "matplotlib-3.5.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:506b210cc6e66a0d1c2bb765d055f4f6bc2745070fb1129203b67e85bbfa5c18"}, + {file = "matplotlib-3.5.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b04fc29bcef04d4e2d626af28d9d892be6aba94856cb46ed52bcb219ceac8943"}, + {file = "matplotlib-3.5.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:577ed20ec9a18d6bdedb4616f5e9e957b4c08563a9f985563a31fd5b10564d2a"}, + {file = "matplotlib-3.5.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e486f60db0cd1c8d68464d9484fd2a94011c1ac8593d765d0211f9daba2bd535"}, + {file = "matplotlib-3.5.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:b71f3a7ca935fc759f2aed7cec06cfe10bc3100fadb5dbd9c435b04e557971e1"}, + {file = "matplotlib-3.5.1-cp38-cp38-win32.whl", hash = "sha256:d24e5bb8028541ce25e59390122f5e48c8506b7e35587e5135efcb6471b4ac6c"}, + {file = "matplotlib-3.5.1-cp38-cp38-win_amd64.whl", hash = "sha256:778d398c4866d8e36ee3bf833779c940b5f57192fa0a549b3ad67bc4c822771b"}, + {file = "matplotlib-3.5.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:bb1c613908f11bac270bc7494d68b1ef6e7c224b7a4204d5dacf3522a41e2bc3"}, + {file = "matplotlib-3.5.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:edf5e4e1d5fb22c18820e8586fb867455de3b109c309cb4fce3aaed85d9468d1"}, + {file = "matplotlib-3.5.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:40e0d7df05e8efe60397c69b467fc8f87a2affeb4d562fe92b72ff8937a2b511"}, + {file = "matplotlib-3.5.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7a350ca685d9f594123f652ba796ee37219bf72c8e0fc4b471473d87121d6d34"}, + {file = "matplotlib-3.5.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3e66497cd990b1a130e21919b004da2f1dc112132c01ac78011a90a0f9229778"}, + {file = "matplotlib-3.5.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:87900c67c0f1728e6db17c6809ec05c025c6624dcf96a8020326ea15378fe8e7"}, + {file = "matplotlib-3.5.1-cp39-cp39-win32.whl", hash = "sha256:b8a4fb2a0c5afbe9604f8a91d7d0f27b1832c3e0b5e365f95a13015822b4cd65"}, + {file = "matplotlib-3.5.1-cp39-cp39-win_amd64.whl", hash = "sha256:fe8d40c434a8e2c68d64c6d6a04e77f21791a93ff6afe0dce169597c110d3079"}, + {file = "matplotlib-3.5.1-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:34a1fc29f8f96e78ec57a5eff5e8d8b53d3298c3be6df61e7aa9efba26929522"}, + {file = "matplotlib-3.5.1-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:b19a761b948e939a9e20173aaae76070025f0024fc8f7ba08bef22a5c8573afc"}, + {file = "matplotlib-3.5.1-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6803299cbf4665eca14428d9e886de62e24f4223ac31ab9c5d6d5339a39782c7"}, + {file = "matplotlib-3.5.1-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:14334b9902ec776461c4b8c6516e26b450f7ebe0b3ef8703bf5cdfbbaecf774a"}, + {file = "matplotlib-3.5.1.tar.gz", hash = "sha256:b2e9810e09c3a47b73ce9cab5a72243a1258f61e7900969097a817232246ce1c"}, ] niapy = [ - {file = "niapy-2.0.0rc18-py3-none-any.whl", hash = "sha256:47388365635ef8123fcf00f2b2243dbac2f77a0b2add2566538e3509db27087d"}, - {file = "niapy-2.0.0rc18.tar.gz", hash = "sha256:1412570dead852068d52f2929a2945e52dc544dfb7edb1923da735f5a15fd323"}, + {file = "niapy-2.0.0-py3-none-any.whl", hash = "sha256:01c34513529d9d4fb4ab7f16a9c9e30799e1706cc1349d37b351c588e0ac4208"}, + {file = "niapy-2.0.0.tar.gz", hash = "sha256:2caddd96e5b8c8029e21e99f6888ade7170587ecd62cf99509da9c209f0ab9eb"}, ] numpy = [ - {file = "numpy-1.21.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:38e8648f9449a549a7dfe8d8755a5979b45b3538520d1e735637ef28e8c2dc50"}, - {file = "numpy-1.21.1-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:fd7d7409fa643a91d0a05c7554dd68aa9c9bb16e186f6ccfe40d6e003156e33a"}, - {file = "numpy-1.21.1-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:a75b4498b1e93d8b700282dc8e655b8bd559c0904b3910b144646dbbbc03e062"}, - {file = "numpy-1.21.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1412aa0aec3e00bc23fbb8664d76552b4efde98fb71f60737c83efbac24112f1"}, - {file = "numpy-1.21.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e46ceaff65609b5399163de5893d8f2a82d3c77d5e56d976c8b5fb01faa6b671"}, - {file = "numpy-1.21.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:c6a2324085dd52f96498419ba95b5777e40b6bcbc20088fddb9e8cbb58885e8e"}, - {file = "numpy-1.21.1-cp37-cp37m-win32.whl", hash = "sha256:73101b2a1fef16602696d133db402a7e7586654682244344b8329cdcbbb82172"}, - {file = "numpy-1.21.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7a708a79c9a9d26904d1cca8d383bf869edf6f8e7650d85dbc77b041e8c5a0f8"}, - {file = "numpy-1.21.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:95b995d0c413f5d0428b3f880e8fe1660ff9396dcd1f9eedbc311f37b5652e16"}, - {file = "numpy-1.21.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:635e6bd31c9fb3d475c8f44a089569070d10a9ef18ed13738b03049280281267"}, - {file = "numpy-1.21.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4a3d5fb89bfe21be2ef47c0614b9c9c707b7362386c9a3ff1feae63e0267ccb6"}, - {file = "numpy-1.21.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:8a326af80e86d0e9ce92bcc1e65c8ff88297de4fa14ee936cb2293d414c9ec63"}, - {file = "numpy-1.21.1-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:791492091744b0fe390a6ce85cc1bf5149968ac7d5f0477288f78c89b385d9af"}, - {file = "numpy-1.21.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0318c465786c1f63ac05d7c4dbcecd4d2d7e13f0959b01b534ea1e92202235c5"}, - {file = "numpy-1.21.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9a513bd9c1551894ee3d31369f9b07460ef223694098cf27d399513415855b68"}, - {file = "numpy-1.21.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:91c6f5fc58df1e0a3cc0c3a717bb3308ff850abdaa6d2d802573ee2b11f674a8"}, - {file = "numpy-1.21.1-cp38-cp38-win32.whl", hash = "sha256:978010b68e17150db8765355d1ccdd450f9fc916824e8c4e35ee620590e234cd"}, - {file = "numpy-1.21.1-cp38-cp38-win_amd64.whl", hash = "sha256:9749a40a5b22333467f02fe11edc98f022133ee1bfa8ab99bda5e5437b831214"}, - {file = "numpy-1.21.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:d7a4aeac3b94af92a9373d6e77b37691b86411f9745190d2c351f410ab3a791f"}, - {file = "numpy-1.21.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d9e7912a56108aba9b31df688a4c4f5cb0d9d3787386b87d504762b6754fbb1b"}, - {file = "numpy-1.21.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:25b40b98ebdd272bc3020935427a4530b7d60dfbe1ab9381a39147834e985eac"}, - {file = "numpy-1.21.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:8a92c5aea763d14ba9d6475803fc7904bda7decc2a0a68153f587ad82941fec1"}, - {file = "numpy-1.21.1-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:05a0f648eb28bae4bcb204e6fd14603de2908de982e761a2fc78efe0f19e96e1"}, - {file = "numpy-1.21.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f01f28075a92eede918b965e86e8f0ba7b7797a95aa8d35e1cc8821f5fc3ad6a"}, - {file = "numpy-1.21.1-cp39-cp39-win32.whl", hash = "sha256:88c0b89ad1cc24a5efbb99ff9ab5db0f9a86e9cc50240177a571fbe9c2860ac2"}, - {file = "numpy-1.21.1-cp39-cp39-win_amd64.whl", hash = "sha256:01721eefe70544d548425a07c80be8377096a54118070b8a62476866d5208e33"}, - {file = "numpy-1.21.1-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:2d4d1de6e6fb3d28781c73fbde702ac97f03d79e4ffd6598b880b2d95d62ead4"}, - {file = "numpy-1.21.1.zip", hash = "sha256:dff4af63638afcc57a3dfb9e4b26d434a7a602d225b42d746ea7fe2edf1342fd"}, + {file = "numpy-1.21.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:301e408a052fdcda5cdcf03021ebafc3c6ea093021bf9d1aa47c54d48bdad166"}, + {file = "numpy-1.21.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a7e8f6216f180f3fd4efb73de5d1eaefb5f5a1ee5b645c67333033e39440e63a"}, + {file = "numpy-1.21.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fc7a7d7b0ed72589fd8b8486b9b42a564f10b8762be8bd4d9df94b807af4a089"}, + {file = "numpy-1.21.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:58ca1d7c8aef6e996112d0ce873ac9dfa1eaf4a1196b4ff7ff73880a09923ba7"}, + {file = "numpy-1.21.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dc4b2fb01f1b4ddbe2453468ea0719f4dbb1f5caa712c8b21bb3dd1480cd30d9"}, + {file = "numpy-1.21.5-cp310-cp310-win_amd64.whl", hash = "sha256:cc1b30205d138d1005adb52087ff45708febbef0e420386f58664f984ef56954"}, + {file = "numpy-1.21.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:08de8472d9f7571f9d51b27b75e827f5296295fa78817032e84464be8bb905bc"}, + {file = "numpy-1.21.5-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:4fe6a006557b87b352c04596a6e3f12a57d6e5f401d804947bd3188e6b0e0e76"}, + {file = "numpy-1.21.5-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:3d893b0871322eaa2f8c7072cdb552d8e2b27645b7875a70833c31e9274d4611"}, + {file = "numpy-1.21.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:341dddcfe3b7b6427a28a27baa59af5ad51baa59bfec3264f1ab287aa3b30b13"}, + {file = "numpy-1.21.5-cp37-cp37m-win32.whl", hash = "sha256:ca9c23848292c6fe0a19d212790e62f398fd9609aaa838859be8459bfbe558aa"}, + {file = "numpy-1.21.5-cp37-cp37m-win_amd64.whl", hash = "sha256:025b497014bc33fc23897859350f284323f32a2fff7654697f5a5fc2a19e9939"}, + {file = "numpy-1.21.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:3a5098df115340fb17fc93867317a947e1dcd978c3888c5ddb118366095851f8"}, + {file = "numpy-1.21.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:311283acf880cfcc20369201bd75da907909afc4666966c7895cbed6f9d2c640"}, + {file = "numpy-1.21.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b545ebadaa2b878c8630e5bcdb97fc4096e779f335fc0f943547c1c91540c815"}, + {file = "numpy-1.21.5-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:c5562bcc1a9b61960fc8950ade44d00e3de28f891af0acc96307c73613d18f6e"}, + {file = "numpy-1.21.5-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:eed2afaa97ec33b4411995be12f8bdb95c87984eaa28d76cf628970c8a2d689a"}, + {file = "numpy-1.21.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:61bada43d494515d5b122f4532af226fdb5ee08fe5b5918b111279843dc6836a"}, + {file = "numpy-1.21.5-cp38-cp38-win32.whl", hash = "sha256:7b9d6b14fc9a4864b08d1ba57d732b248f0e482c7b2ff55c313137e3ed4d8449"}, + {file = "numpy-1.21.5-cp38-cp38-win_amd64.whl", hash = "sha256:dbce7adeb66b895c6aaa1fad796aaefc299ced597f6fbd9ceddb0dd735245354"}, + {file = "numpy-1.21.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:507c05c7a37b3683eb08a3ff993bd1ee1e6c752f77c2f275260533b265ecdb6c"}, + {file = "numpy-1.21.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:00c9fa73a6989895b8815d98300a20ac993c49ac36c8277e8ffeaa3631c0dbbb"}, + {file = "numpy-1.21.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:69a5a8d71c308d7ef33ef72371c2388a90e3495dbb7993430e674006f94797d5"}, + {file = "numpy-1.21.5-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:2d8adfca843bc46ac199a4645233f13abf2011a0b2f4affc5c37cd552626f27b"}, + {file = "numpy-1.21.5-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:c293d3c0321996cd8ffe84215ffe5d269fd9d1d12c6f4ffe2b597a7c30d3e593"}, + {file = "numpy-1.21.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3c978544be9e04ed12016dd295a74283773149b48f507d69b36f91aa90a643e5"}, + {file = "numpy-1.21.5-cp39-cp39-win32.whl", hash = "sha256:2a9add27d7fc0fdb572abc3b2486eb3b1395da71e0254c5552b2aad2a18b5441"}, + {file = "numpy-1.21.5-cp39-cp39-win_amd64.whl", hash = "sha256:1964db2d4a00348b7a60ee9d013c8cb0c566644a589eaa80995126eac3b99ced"}, + {file = "numpy-1.21.5-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:a7c4b701ca418cd39e28ec3b496e6388fe06de83f5f0cb74794fa31cfa384c02"}, + {file = "numpy-1.21.5.zip", hash = "sha256:6a5928bc6241264dce5ed509e66f33676fc97f464e7a919edc672fb5532221ee"}, + {file = "numpy-1.22.2-cp310-cp310-macosx_10_14_x86_64.whl", hash = "sha256:515a8b6edbb904594685da6e176ac9fbea8f73a5ebae947281de6613e27f1956"}, + {file = "numpy-1.22.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:76a4f9bce0278becc2da7da3b8ef854bed41a991f4226911a24a9711baad672c"}, + {file = "numpy-1.22.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:168259b1b184aa83a514f307352c25c56af111c269ffc109d9704e81f72e764b"}, + {file = "numpy-1.22.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3556c5550de40027d3121ebbb170f61bbe19eb639c7ad0c7b482cd9b560cd23b"}, + {file = "numpy-1.22.2-cp310-cp310-win_amd64.whl", hash = "sha256:aafa46b5a39a27aca566198d3312fb3bde95ce9677085efd02c86f7ef6be4ec7"}, + {file = "numpy-1.22.2-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:55535c7c2f61e2b2fc817c5cbe1af7cb907c7f011e46ae0a52caa4be1f19afe2"}, + {file = "numpy-1.22.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:60cb8e5933193a3cc2912ee29ca331e9c15b2da034f76159b7abc520b3d1233a"}, + {file = "numpy-1.22.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0b536b6840e84c1c6a410f3a5aa727821e6108f3454d81a5cd5900999ef04f89"}, + {file = "numpy-1.22.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2638389562bda1635b564490d76713695ff497242a83d9b684d27bb4a6cc9d7a"}, + {file = "numpy-1.22.2-cp38-cp38-win32.whl", hash = "sha256:6767ad399e9327bfdbaa40871be4254d1995f4a3ca3806127f10cec778bd9896"}, + {file = "numpy-1.22.2-cp38-cp38-win_amd64.whl", hash = "sha256:03ae5850619abb34a879d5f2d4bb4dcd025d6d8fb72f5e461dae84edccfe129f"}, + {file = "numpy-1.22.2-cp39-cp39-macosx_10_14_x86_64.whl", hash = "sha256:d76a26c5118c4d96e264acc9e3242d72e1a2b92e739807b3b69d8d47684b6677"}, + {file = "numpy-1.22.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:15efb7b93806d438e3bc590ca8ef2f953b0ce4f86f337ef4559d31ec6cf9d7dd"}, + {file = "numpy-1.22.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:badca914580eb46385e7f7e4e426fea6de0a37b9e06bec252e481ae7ec287082"}, + {file = "numpy-1.22.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:94dd11d9f13ea1be17bac39c1942f527cbf7065f94953cf62dfe805653da2f8f"}, + {file = "numpy-1.22.2-cp39-cp39-win32.whl", hash = "sha256:8cf33634b60c9cef346663a222d9841d3bbbc0a2f00221d6bcfd0d993d5543f6"}, + {file = "numpy-1.22.2-cp39-cp39-win_amd64.whl", hash = "sha256:59153979d60f5bfe9e4c00e401e24dfe0469ef8da6d68247439d3278f30a180f"}, + {file = "numpy-1.22.2-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a176959b6e7e00b5a0d6f549a479f869829bfd8150282c590deee6d099bbb6e"}, + {file = "numpy-1.22.2.zip", hash = "sha256:076aee5a3763d41da6bef9565fdf3cb987606f567cd8b104aded2b38b7b47abf"}, ] openpyxl = [ {file = "openpyxl-3.0.9-py2.py3-none-any.whl", hash = "sha256:8f3b11bd896a95468a4ab162fc4fcd260d46157155d1f8bfaabb99d88cfcf79f"}, @@ -483,64 +530,89 @@ packaging = [ {file = "packaging-21.3.tar.gz", hash = "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb"}, ] pandas = [ - {file = "pandas-1.1.5-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:bf23a3b54d128b50f4f9d4675b3c1857a688cc6731a32f931837d72effb2698d"}, - {file = "pandas-1.1.5-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:5a780260afc88268a9d3ac3511d8f494fdcf637eece62fb9eb656a63d53eb7ca"}, - {file = "pandas-1.1.5-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:b61080750d19a0122469ab59b087380721d6b72a4e7d962e4d7e63e0c4504814"}, - {file = "pandas-1.1.5-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:0de3ddb414d30798cbf56e642d82cac30a80223ad6fe484d66c0ce01a84d6f2f"}, - {file = "pandas-1.1.5-cp36-cp36m-win32.whl", hash = "sha256:70865f96bb38fec46f7ebd66d4b5cfd0aa6b842073f298d621385ae3898d28b5"}, - {file = "pandas-1.1.5-cp36-cp36m-win_amd64.whl", hash = "sha256:19a2148a1d02791352e9fa637899a78e371a3516ac6da5c4edc718f60cbae648"}, - {file = "pandas-1.1.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:26fa92d3ac743a149a31b21d6f4337b0594b6302ea5575b37af9ca9611e8981a"}, - {file = "pandas-1.1.5-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:c16d59c15d946111d2716856dd5479221c9e4f2f5c7bc2d617f39d870031e086"}, - {file = "pandas-1.1.5-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:3be7a7a0ca71a2640e81d9276f526bca63505850add10206d0da2e8a0a325dae"}, - {file = "pandas-1.1.5-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:573fba5b05bf2c69271a32e52399c8de599e4a15ab7cec47d3b9c904125ab788"}, - {file = "pandas-1.1.5-cp37-cp37m-win32.whl", hash = "sha256:21b5a2b033380adbdd36b3116faaf9a4663e375325831dac1b519a44f9e439bb"}, - {file = "pandas-1.1.5-cp37-cp37m-win_amd64.whl", hash = "sha256:24c7f8d4aee71bfa6401faeba367dd654f696a77151a8a28bc2013f7ced4af98"}, - {file = "pandas-1.1.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2860a97cbb25444ffc0088b457da0a79dc79f9c601238a3e0644312fcc14bf11"}, - {file = "pandas-1.1.5-cp38-cp38-manylinux1_i686.whl", hash = "sha256:5008374ebb990dad9ed48b0f5d0038124c73748f5384cc8c46904dace27082d9"}, - {file = "pandas-1.1.5-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:2c2f7c670ea4e60318e4b7e474d56447cf0c7d83b3c2a5405a0dbb2600b9c48e"}, - {file = "pandas-1.1.5-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:0a643bae4283a37732ddfcecab3f62dd082996021b980f580903f4e8e01b3c5b"}, - {file = "pandas-1.1.5-cp38-cp38-win32.whl", hash = "sha256:5447ea7af4005b0daf695a316a423b96374c9c73ffbd4533209c5ddc369e644b"}, - {file = "pandas-1.1.5-cp38-cp38-win_amd64.whl", hash = "sha256:4c62e94d5d49db116bef1bd5c2486723a292d79409fc9abd51adf9e05329101d"}, - {file = "pandas-1.1.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:731568be71fba1e13cae212c362f3d2ca8932e83cb1b85e3f1b4dd77d019254a"}, - {file = "pandas-1.1.5-cp39-cp39-manylinux1_i686.whl", hash = "sha256:c61c043aafb69329d0f961b19faa30b1dab709dd34c9388143fc55680059e55a"}, - {file = "pandas-1.1.5-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:2b1c6cd28a0dfda75c7b5957363333f01d370936e4c6276b7b8e696dd500582a"}, - {file = "pandas-1.1.5-cp39-cp39-win32.whl", hash = "sha256:c94ff2780a1fd89f190390130d6d36173ca59fcfb3fe0ff596f9a56518191ccb"}, - {file = "pandas-1.1.5-cp39-cp39-win_amd64.whl", hash = "sha256:edda9bacc3843dfbeebaf7a701763e68e741b08fccb889c003b0a52f0ee95782"}, - {file = "pandas-1.1.5.tar.gz", hash = "sha256:f10fc41ee3c75a474d3bdf68d396f10782d013d7f67db99c0efbfd0acb99701b"}, + {file = "pandas-1.3.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:62d5b5ce965bae78f12c1c0df0d387899dd4211ec0bdc52822373f13a3a022b9"}, + {file = "pandas-1.3.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:adfeb11be2d54f275142c8ba9bf67acee771b7186a5745249c7d5a06c670136b"}, + {file = "pandas-1.3.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:60a8c055d58873ad81cae290d974d13dd479b82cbb975c3e1fa2cf1920715296"}, + {file = "pandas-1.3.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fd541ab09e1f80a2a1760032d665f6e032d8e44055d602d65eeea6e6e85498cb"}, + {file = "pandas-1.3.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2651d75b9a167cc8cc572cf787ab512d16e316ae00ba81874b560586fa1325e0"}, + {file = "pandas-1.3.5-cp310-cp310-win_amd64.whl", hash = "sha256:aaf183a615ad790801fa3cf2fa450e5b6d23a54684fe386f7e3208f8b9bfbef6"}, + {file = "pandas-1.3.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:344295811e67f8200de2390093aeb3c8309f5648951b684d8db7eee7d1c81fb7"}, + {file = "pandas-1.3.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:552020bf83b7f9033b57cbae65589c01e7ef1544416122da0c79140c93288f56"}, + {file = "pandas-1.3.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5cce0c6bbeb266b0e39e35176ee615ce3585233092f685b6a82362523e59e5b4"}, + {file = "pandas-1.3.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7d28a3c65463fd0d0ba8bbb7696b23073efee0510783340a44b08f5e96ffce0c"}, + {file = "pandas-1.3.5-cp37-cp37m-win32.whl", hash = "sha256:a62949c626dd0ef7de11de34b44c6475db76995c2064e2d99c6498c3dba7fe58"}, + {file = "pandas-1.3.5-cp37-cp37m-win_amd64.whl", hash = "sha256:8025750767e138320b15ca16d70d5cdc1886e8f9cc56652d89735c016cd8aea6"}, + {file = "pandas-1.3.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:fe95bae4e2d579812865db2212bb733144e34d0c6785c0685329e5b60fcb85dd"}, + {file = "pandas-1.3.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f261553a1e9c65b7a310302b9dbac31cf0049a51695c14ebe04e4bfd4a96f02"}, + {file = "pandas-1.3.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8b6dbec5f3e6d5dc80dcfee250e0a2a652b3f28663492f7dab9a24416a48ac39"}, + {file = "pandas-1.3.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d3bc49af96cd6285030a64779de5b3688633a07eb75c124b0747134a63f4c05f"}, + {file = "pandas-1.3.5-cp38-cp38-win32.whl", hash = "sha256:b6b87b2fb39e6383ca28e2829cddef1d9fc9e27e55ad91ca9c435572cdba51bf"}, + {file = "pandas-1.3.5-cp38-cp38-win_amd64.whl", hash = "sha256:a395692046fd8ce1edb4c6295c35184ae0c2bbe787ecbe384251da609e27edcb"}, + {file = "pandas-1.3.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:bd971a3f08b745a75a86c00b97f3007c2ea175951286cdda6abe543e687e5f2f"}, + {file = "pandas-1.3.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:37f06b59e5bc05711a518aa10beaec10942188dccb48918bb5ae602ccbc9f1a0"}, + {file = "pandas-1.3.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2c21778a688d3712d35710501f8001cdbf96eb70a7c587a3d5613573299fdca6"}, + {file = "pandas-1.3.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3345343206546545bc26a05b4602b6a24385b5ec7c75cb6059599e3d56831da2"}, + {file = "pandas-1.3.5-cp39-cp39-win32.whl", hash = "sha256:c69406a2808ba6cf580c2255bcf260b3f214d2664a3a4197d0e640f573b46fd3"}, + {file = "pandas-1.3.5-cp39-cp39-win_amd64.whl", hash = "sha256:32e1a26d5ade11b547721a72f9bfc4bd113396947606e00d5b4a5b79b3dcb006"}, + {file = "pandas-1.3.5.tar.gz", hash = "sha256:1e4285f5de1012de20ca46b188ccf33521bff61ba5c5ebd78b4fb28e5416a9f1"}, + {file = "pandas-1.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3dfb32ed50122fe8c5e7f2b8d97387edd742cc78f9ec36f007ee126cd3720907"}, + {file = "pandas-1.4.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0259cd11e7e6125aaea3af823b80444f3adad6149ff4c97fef760093598b3e34"}, + {file = "pandas-1.4.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:96e9ece5759f9b47ae43794b6359bbc54805d76e573b161ae770c1ea59393106"}, + {file = "pandas-1.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:508c99debccd15790d526ce6b1624b97a5e1e4ca5b871319fb0ebfd46b8f4dad"}, + {file = "pandas-1.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e6a7bbbb7950063bfc942f8794bc3e31697c020a14f1cd8905fc1d28ec674a01"}, + {file = "pandas-1.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:c614001129b2a5add5e3677c3a213a9e6fd376204cb8d17c04e84ff7dfc02a73"}, + {file = "pandas-1.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:4e1176f45981c8ccc8161bc036916c004ca51037a7ed73f2d2a9857e6dbe654f"}, + {file = "pandas-1.4.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:bbb15ad79050e8b8d39ec40dd96a30cd09b886a2ae8848d0df1abba4d5502a67"}, + {file = "pandas-1.4.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:6d6ad1da00c7cc7d8dd1559a6ba59ba3973be6b15722d49738b2be0977eb8a0c"}, + {file = "pandas-1.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:358b0bc98a5ff067132d23bf7a2242ee95db9ea5b7bbc401cf79205f11502fd3"}, + {file = "pandas-1.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6105af6533f8b63a43ea9f08a2ede04e8f43e49daef0209ab0d30352bcf08bee"}, + {file = "pandas-1.4.1-cp38-cp38-win32.whl", hash = "sha256:04dd15d9db538470900c851498e532ef28d4e56bfe72c9523acb32042de43dfb"}, + {file = "pandas-1.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:1b384516dbb4e6aae30e3464c2e77c563da5980440fbdfbd0968e3942f8f9d70"}, + {file = "pandas-1.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:f02e85e6d832be37d7f16cf6ac8bb26b519ace3e5f3235564a91c7f658ab2a43"}, + {file = "pandas-1.4.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:0b1a13f647e4209ed7dbb5da3497891d0045da9785327530ab696417ef478f84"}, + {file = "pandas-1.4.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:19f7c632436b1b4f84615c3b127bbd7bc603db95e3d4332ed259dc815c9aaa26"}, + {file = "pandas-1.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ea47ba1d6f359680130bd29af497333be6110de8f4c35b9211eec5a5a9630fa"}, + {file = "pandas-1.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2e5a7a1e0ecaac652326af627a3eca84886da9e667d68286866d4e33f6547caf"}, + {file = "pandas-1.4.1-cp39-cp39-win32.whl", hash = "sha256:1d85d5f6be66dfd6d1d8d13b9535e342a2214260f1852654b19fa4d7b8d1218b"}, + {file = "pandas-1.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:3129a35d9dad1d80c234dd78f8f03141b914395d23f97cf92a366dcd19f8f8bf"}, + {file = "pandas-1.4.1.tar.gz", hash = "sha256:8db93ec98ac7cb5f8ac1420c10f5e3c43533153f253fe7fb6d891cf5aa2b80d2"}, ] pillow = [ - {file = "Pillow-9.0.0-cp310-cp310-macosx_10_10_universal2.whl", hash = "sha256:113723312215b25c22df1fdf0e2da7a3b9c357a7d24a93ebbe80bfda4f37a8d4"}, - {file = "Pillow-9.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:bb47a548cea95b86494a26c89d153fd31122ed65255db5dcbc421a2d28eb3379"}, - {file = "Pillow-9.0.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:31b265496e603985fad54d52d11970383e317d11e18e856971bdbb86af7242a4"}, - {file = "Pillow-9.0.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d154ed971a4cc04b93a6d5b47f37948d1f621f25de3e8fa0c26b2d44f24e3e8f"}, - {file = "Pillow-9.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80fe92813d208ce8aa7d76da878bdc84b90809f79ccbad2a288e9bcbeac1d9bd"}, - {file = "Pillow-9.0.0-cp310-cp310-win32.whl", hash = "sha256:d5dcea1387331c905405b09cdbfb34611050cc52c865d71f2362f354faee1e9f"}, - {file = "Pillow-9.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:52abae4c96b5da630a8b4247de5428f593465291e5b239f3f843a911a3cf0105"}, - {file = "Pillow-9.0.0-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:72c3110228944019e5f27232296c5923398496b28be42535e3b2dc7297b6e8b6"}, - {file = "Pillow-9.0.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:97b6d21771da41497b81652d44191489296555b761684f82b7b544c49989110f"}, - {file = "Pillow-9.0.0-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:72f649d93d4cc4d8cf79c91ebc25137c358718ad75f99e99e043325ea7d56100"}, - {file = "Pillow-9.0.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7aaf07085c756f6cb1c692ee0d5a86c531703b6e8c9cae581b31b562c16b98ce"}, - {file = "Pillow-9.0.0-cp37-cp37m-win32.whl", hash = "sha256:03b27b197deb4ee400ed57d8d4e572d2d8d80f825b6634daf6e2c18c3c6ccfa6"}, - {file = "Pillow-9.0.0-cp37-cp37m-win_amd64.whl", hash = "sha256:a09a9d4ec2b7887f7a088bbaacfd5c07160e746e3d47ec5e8050ae3b2a229e9f"}, - {file = "Pillow-9.0.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:490e52e99224858f154975db61c060686df8a6b3f0212a678e5d2e2ce24675c9"}, - {file = "Pillow-9.0.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:500d397ddf4bbf2ca42e198399ac13e7841956c72645513e8ddf243b31ad2128"}, - {file = "Pillow-9.0.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ebd8b9137630a7bbbff8c4b31e774ff05bbb90f7911d93ea2c9371e41039b52"}, - {file = "Pillow-9.0.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fd0e5062f11cb3e730450a7d9f323f4051b532781026395c4323b8ad055523c4"}, - {file = "Pillow-9.0.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f3b4522148586d35e78313db4db0df4b759ddd7649ef70002b6c3767d0fdeb7"}, - {file = "Pillow-9.0.0-cp38-cp38-win32.whl", hash = "sha256:0b281fcadbb688607ea6ece7649c5d59d4bbd574e90db6cd030e9e85bde9fecc"}, - {file = "Pillow-9.0.0-cp38-cp38-win_amd64.whl", hash = "sha256:b5050d681bcf5c9f2570b93bee5d3ec8ae4cf23158812f91ed57f7126df91762"}, - {file = "Pillow-9.0.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:c2067b3bb0781f14059b112c9da5a91c80a600a97915b4f48b37f197895dd925"}, - {file = "Pillow-9.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2d16b6196fb7a54aff6b5e3ecd00f7c0bab1b56eee39214b2b223a9d938c50af"}, - {file = "Pillow-9.0.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:98cb63ca63cb61f594511c06218ab4394bf80388b3d66cd61d0b1f63ee0ea69f"}, - {file = "Pillow-9.0.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bc462d24500ba707e9cbdef436c16e5c8cbf29908278af053008d9f689f56dee"}, - {file = "Pillow-9.0.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3586e12d874ce2f1bc875a3ffba98732ebb12e18fb6d97be482bd62b56803281"}, - {file = "Pillow-9.0.0-cp39-cp39-win32.whl", hash = "sha256:68e06f8b2248f6dc8b899c3e7ecf02c9f413aab622f4d6190df53a78b93d97a5"}, - {file = "Pillow-9.0.0-cp39-cp39-win_amd64.whl", hash = "sha256:6579f9ba84a3d4f1807c4aab4be06f373017fc65fff43498885ac50a9b47a553"}, - {file = "Pillow-9.0.0-pp37-pypy37_pp73-macosx_10_10_x86_64.whl", hash = "sha256:47f5cf60bcb9fbc46011f75c9b45a8b5ad077ca352a78185bd3e7f1d294b98bb"}, - {file = "Pillow-9.0.0-pp37-pypy37_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2fd8053e1f8ff1844419842fd474fc359676b2e2a2b66b11cc59f4fa0a301315"}, - {file = "Pillow-9.0.0-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c5439bfb35a89cac50e81c751317faea647b9a3ec11c039900cd6915831064d"}, - {file = "Pillow-9.0.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:95545137fc56ce8c10de646074d242001a112a92de169986abd8c88c27566a05"}, - {file = "Pillow-9.0.0.tar.gz", hash = "sha256:ee6e2963e92762923956fe5d3479b1fdc3b76c83f290aad131a2f98c3df0593e"}, + {file = "Pillow-9.0.1-1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a5d24e1d674dd9d72c66ad3ea9131322819ff86250b30dc5821cbafcfa0b96b4"}, + {file = "Pillow-9.0.1-1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2632d0f846b7c7600edf53c48f8f9f1e13e62f66a6dbc15191029d950bfed976"}, + {file = "Pillow-9.0.1-1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b9618823bd237c0d2575283f2939655f54d51b4527ec3972907a927acbcc5bfc"}, + {file = "Pillow-9.0.1-cp310-cp310-macosx_10_10_universal2.whl", hash = "sha256:9bfdb82cdfeccec50aad441afc332faf8606dfa5e8efd18a6692b5d6e79f00fd"}, + {file = "Pillow-9.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5100b45a4638e3c00e4d2320d3193bdabb2d75e79793af7c3eb139e4f569f16f"}, + {file = "Pillow-9.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:528a2a692c65dd5cafc130de286030af251d2ee0483a5bf50c9348aefe834e8a"}, + {file = "Pillow-9.0.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0f29d831e2151e0b7b39981756d201f7108d3d215896212ffe2e992d06bfe049"}, + {file = "Pillow-9.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:855c583f268edde09474b081e3ddcd5cf3b20c12f26e0d434e1386cc5d318e7a"}, + {file = "Pillow-9.0.1-cp310-cp310-win32.whl", hash = "sha256:d9d7942b624b04b895cb95af03a23407f17646815495ce4547f0e60e0b06f58e"}, + {file = "Pillow-9.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:81c4b81611e3a3cb30e59b0cf05b888c675f97e3adb2c8672c3154047980726b"}, + {file = "Pillow-9.0.1-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:413ce0bbf9fc6278b2d63309dfeefe452835e1c78398efb431bab0672fe9274e"}, + {file = "Pillow-9.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:80fe64a6deb6fcfdf7b8386f2cf216d329be6f2781f7d90304351811fb591360"}, + {file = "Pillow-9.0.1-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cef9c85ccbe9bee00909758936ea841ef12035296c748aaceee535969e27d31b"}, + {file = "Pillow-9.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1d19397351f73a88904ad1aee421e800fe4bbcd1aeee6435fb62d0a05ccd1030"}, + {file = "Pillow-9.0.1-cp37-cp37m-win32.whl", hash = "sha256:d21237d0cd37acded35154e29aec853e945950321dd2ffd1a7d86fe686814669"}, + {file = "Pillow-9.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:ede5af4a2702444a832a800b8eb7f0a7a1c0eed55b644642e049c98d589e5092"}, + {file = "Pillow-9.0.1-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:b5b3f092fe345c03bca1e0b687dfbb39364b21ebb8ba90e3fa707374b7915204"}, + {file = "Pillow-9.0.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:335ace1a22325395c4ea88e00ba3dc89ca029bd66bd5a3c382d53e44f0ccd77e"}, + {file = "Pillow-9.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:db6d9fac65bd08cea7f3540b899977c6dee9edad959fa4eaf305940d9cbd861c"}, + {file = "Pillow-9.0.1-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f154d173286a5d1863637a7dcd8c3437bb557520b01bddb0be0258dcb72696b5"}, + {file = "Pillow-9.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:14d4b1341ac07ae07eb2cc682f459bec932a380c3b122f5540432d8977e64eae"}, + {file = "Pillow-9.0.1-cp38-cp38-win32.whl", hash = "sha256:effb7749713d5317478bb3acb3f81d9d7c7f86726d41c1facca068a04cf5bb4c"}, + {file = "Pillow-9.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:7f7609a718b177bf171ac93cea9fd2ddc0e03e84d8fa4e887bdfc39671d46b00"}, + {file = "Pillow-9.0.1-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:80ca33961ced9c63358056bd08403ff866512038883e74f3a4bf88ad3eb66838"}, + {file = "Pillow-9.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1c3c33ac69cf059bbb9d1a71eeaba76781b450bc307e2291f8a4764d779a6b28"}, + {file = "Pillow-9.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:12875d118f21cf35604176872447cdb57b07126750a33748bac15e77f90f1f9c"}, + {file = "Pillow-9.0.1-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:514ceac913076feefbeaf89771fd6febde78b0c4c1b23aaeab082c41c694e81b"}, + {file = "Pillow-9.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d3c5c79ab7dfce6d88f1ba639b77e77a17ea33a01b07b99840d6ed08031cb2a7"}, + {file = "Pillow-9.0.1-cp39-cp39-win32.whl", hash = "sha256:718856856ba31f14f13ba885ff13874be7fefc53984d2832458f12c38205f7f7"}, + {file = "Pillow-9.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:f25ed6e28ddf50de7e7ea99d7a976d6a9c415f03adcaac9c41ff6ff41b6d86ac"}, + {file = "Pillow-9.0.1-pp37-pypy37_pp73-macosx_10_10_x86_64.whl", hash = "sha256:011233e0c42a4a7836498e98c1acf5e744c96a67dd5032a6f666cc1fb97eab97"}, + {file = "Pillow-9.0.1-pp37-pypy37_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:253e8a302a96df6927310a9d44e6103055e8fb96a6822f8b7f514bb7ef77de56"}, + {file = "Pillow-9.0.1-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6295f6763749b89c994fcb6d8a7f7ce03c3992e695f89f00b741b4580b199b7e"}, + {file = "Pillow-9.0.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:a9f44cd7e162ac6191491d7249cceb02b8116b0f7e847ee33f739d7cb1ea1f70"}, + {file = "Pillow-9.0.1.tar.gz", hash = "sha256:6c8bc8238a7dfdaf7a75f5ec5a663f4173f8c367e5a39f87e720495e1eed75fa"}, ] pluggy = [ {file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"}, @@ -551,12 +623,12 @@ py = [ {file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"}, ] pyparsing = [ - {file = "pyparsing-3.0.6-py3-none-any.whl", hash = "sha256:04ff808a5b90911829c55c4e26f75fa5ca8a2f5f36aa3a51f68e27033341d3e4"}, - {file = "pyparsing-3.0.6.tar.gz", hash = "sha256:d9bdec0013ef1eb5a84ab39a3b3868911598afa494f5faa038647101504e2b81"}, + {file = "pyparsing-3.0.7-py3-none-any.whl", hash = "sha256:a6c06a88f252e6c322f65faf8f418b16213b51bdfaece0524c1c1bc30c63c484"}, + {file = "pyparsing-3.0.7.tar.gz", hash = "sha256:18ee9022775d270c55187733956460083db60b37d0d0fb357445f3094eed3eea"}, ] pytest = [ - {file = "pytest-6.2.5-py3-none-any.whl", hash = "sha256:7310f8d27bc79ced999e760ca304d69f6ba6c6649c0b60fb0e04a4a77cacc134"}, - {file = "pytest-6.2.5.tar.gz", hash = "sha256:131b36680866a76e6781d13f101efb86cf674ebb9762eb70d3082b6f29889e89"}, + {file = "pytest-7.0.1-py3-none-any.whl", hash = "sha256:9ce3ff477af913ecf6321fe337b93a2c0dcf2a0a1439c43f5452112c1e4280db"}, + {file = "pytest-7.0.1.tar.gz", hash = "sha256:e30905a0c131d3d94b89624a1cc5afec3e0ba2fbdb151867d8e0ebd49850f171"}, ] python-dateutil = [ {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"}, @@ -567,26 +639,22 @@ pytz = [ {file = "pytz-2021.3.tar.gz", hash = "sha256:acad2d8b20a1af07d4e4c9d2e9285c5ed9104354062f275f3fcd88dcef4f1326"}, ] setuptools-scm = [ - {file = "setuptools_scm-6.3.2-py3-none-any.whl", hash = "sha256:4c64444b1d49c4063ae60bfe1680f611c8b13833d556fd1d6050c0023162a119"}, - {file = "setuptools_scm-6.3.2.tar.gz", hash = "sha256:a49aa8081eeb3514eb9728fa5040f2eaa962d6c6f4ec9c32f6c1fba88f88a0f2"}, + {file = "setuptools_scm-6.4.2-py3-none-any.whl", hash = "sha256:acea13255093849de7ccb11af9e1fb8bde7067783450cee9ef7a93139bddf6d4"}, + {file = "setuptools_scm-6.4.2.tar.gz", hash = "sha256:6833ac65c6ed9711a4d5d2266f8024cfa07c533a0e55f4c12f6eff280a5a9e30"}, ] six = [ {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, ] -toml = [ - {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, - {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, -] tomli = [ - {file = "tomli-1.2.2-py3-none-any.whl", hash = "sha256:f04066f68f5554911363063a30b108d2b5a5b1a010aa8b6132af78489fe3aade"}, - {file = "tomli-1.2.2.tar.gz", hash = "sha256:c6ce0015eb38820eaf32b5db832dbc26deb3dd427bd5f6556cf0acac2c214fee"}, + {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, + {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, ] typing-extensions = [ - {file = "typing_extensions-4.0.0-py3-none-any.whl", hash = "sha256:829704698b22e13ec9eaf959122315eabb370b0884400e9818334d8b677023d9"}, - {file = "typing_extensions-4.0.0.tar.gz", hash = "sha256:2cdf80e4e04866a9b3689a51869016d36db0814d84b8d8a568d22781d45d27ed"}, + {file = "typing_extensions-4.1.1-py3-none-any.whl", hash = "sha256:21c85e0fe4b9a155d0799430b0ad741cdce7e359660ccbd8b530613e8df88ce2"}, + {file = "typing_extensions-4.1.1.tar.gz", hash = "sha256:1a9462dcc3347a79b1f1c0271fbe79e844580bb598bafa1ed208b94da3cdcd42"}, ] zipp = [ - {file = "zipp-3.6.0-py3-none-any.whl", hash = "sha256:9fe5ea21568a0a70e50f273397638d39b03353731e6cbbb3fd8502a33fec40bc"}, - {file = "zipp-3.6.0.tar.gz", hash = "sha256:71c644c5369f4a6e07636f0aa966270449561fcea2e3d6747b8d23efaa9d7832"}, + {file = "zipp-3.7.0-py3-none-any.whl", hash = "sha256:b47250dd24f92b7dd6a0a8fc5244da14608f3ca90a5efcd37a3b1642fac9a375"}, + {file = "zipp-3.7.0.tar.gz", hash = "sha256:9f50f446828eb9d45b267433fd3e9da8d801f614129124863f9c51ebceafb87d"}, ] diff --git a/pyproject.toml b/pyproject.toml index af2120e..7949d22 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -2,15 +2,23 @@ name = "niaarm" version = "0.1.0" description = "Nature-inspired algorithms for Association Rule Mining" -authors = ["Iztok Fister, Jr. ", "Žiga Stupan ", "Žiga Stupan "] readme = "README.md" [tool.poetry.dependencies] python = "^3.7" -niapy = "*" +niapy = "^2.0.0" +numpy = [ + { version = "^1.21.5", python = ">=3.7,<3.11" }, + { version = "^1.22.0", python = "^3.11" } +] +pandas = [ + { version = "^1.3.5", python = ">=3.7.1,<3.9" }, + { version = "^1.4.0", python = "^3.8" } +] [tool.poetry.dev-dependencies] -pytest = "^6.2.5" +pytest = "^7.0.1" [build-system] requires = ["poetry-core>=1.0.0"] From 41f5e75478ffdbae66a7d8a048f49cc8897fd44f Mon Sep 17 00:00:00 2001 From: zStupan Date: Sat, 26 Feb 2022 00:53:38 +0100 Subject: [PATCH 2/5] Refactor --- basic_run.py | 17 +--- niaarm/association_rule.py | 113 ++++++++---------------- niaarm/dataset.py | 73 ++++----------- niaarm/niaarm.py | 71 +++++++-------- niaarm/stats.py | 33 ++++--- niaarm/tests/test_coverage.py | 2 +- niaarm/tests/test_cut_point.py | 5 +- niaarm/tests/test_read_csv.py | 12 +-- niaarm/tests/test_rule_building.py | 4 +- niaarm/tests/test_shrinkage.py | 2 +- niaarm/tests/test_support_confidence.py | 4 +- 11 files changed, 117 insertions(+), 219 deletions(-) diff --git a/basic_run.py b/basic_run.py index 06c504a..e7f35d1 100644 --- a/basic_run.py +++ b/basic_run.py @@ -3,26 +3,15 @@ from niapy.algorithms.basic import ParticleSwarmAlgorithm, DifferentialEvolution from niapy.task import Task, OptimizationType -# load dataset from csv +# load and preprocess dataset from csv data = Dataset("datasets/Abalone.csv") -# preprocess dataset and obtain features -features = data.get_features() - -# calculate dimension of the problem -dimension = data.calculate_dimension_of_individual() - -# obtain transaction database -transactions = data.transaction_data - # Create a problem::: # dimension represents dimension of the problem; -# 0, 1 represents the range of search space # features represent the list of features, while transactions depicts the list of transactions # the following 4 elements represent weights (support, confidence, coverage, shrinkage) # None defines that criteria is omitted and is therefore excluded from fitness function -# final element represents the filename in which obtained rules in csv format are stored -problem = NiaARM(dimension, 0, 1, features, transactions, 1.0, 1.0, None, None, "results.csv") +problem = NiaARM(data.dimension, data.features, data.transactions, alpha=1.0, beta=1.0) # build niapy task task = Task( @@ -47,4 +36,4 @@ problem.sort_rules() # export all rules to csv -problem.rules_to_csv() +problem.rules_to_csv('output.csv') diff --git a/niaarm/association_rule.py b/niaarm/association_rule.py index b586d5e..d52200f 100644 --- a/niaarm/association_rule.py +++ b/niaarm/association_rule.py @@ -1,6 +1,3 @@ -import math - - class AssociationRule: r"""Class for main operations and quality measures. @@ -33,10 +30,10 @@ def build_rule(self, vector): if vector[vector_position] > vector[threshold_position]: if self.features[current_feature].dtype == 'float': - border1 = (vector[vector_position] * (self.features[current_feature].max_val - \ + border1 = (vector[vector_position] * (self.features[current_feature].max_val - self.features[current_feature].min_val)) + self.features[current_feature].min_val vector_position = vector_position + 1 - border2 = (vector[vector_position] * (self.features[current_feature].max_val - \ + border2 = (vector[vector_position] * (self.features[current_feature].max_val - self.features[current_feature].min_val)) + self.features[current_feature].min_val if border1 > border2: @@ -73,11 +70,9 @@ def build_rule(self, vector): else: categories = self.features[current_feature].categories - selected = round(vector[vector_position] - * (len(categories) - 1)) + selected = round(vector[vector_position] * (len(categories) - 1)) - rule.append( - [self.features[current_feature].categories[selected]]) + rule.append([self.features[current_feature].categories[selected]]) else: rule.append('NO') @@ -141,26 +136,20 @@ def calculate_support_confidence( conf_counter = 0 # firstly antecedent - for i in range(0, len(transactions)): + for i in range(len(transactions)): match1 = 0 match2 = 0 - for l in range(len(antecedent)): - if self.features[self.permutation[l] - ].dtype == 'float' or self.features[self.permutation[l]].dtype == 'int': - if antecedent[l] == 'NO': - pass - else: - border = antecedent[l] - if (float(transactions[i][self.permutation[l]]) >= border[0]) and ( - float(transactions[i][self.permutation[l]]) <= border[1]): + for j in range(len(antecedent)): + if self.features[self.permutation[j]].dtype == 'float' or self.features[self.permutation[j]].dtype == 'int': + if antecedent[j] != 'NO': + border = antecedent[j] + if (float(transactions[i][self.permutation[j]]) >= border[0]) and ( + float(transactions[i][self.permutation[j]]) <= border[1]): match1 = match1 + 1 - elif self.features[self.permutation[l]].dtype == 'cat': - if antecedent[l] == 'NO': - pass - else: - ant = antecedent[l] - if transactions[i][self.permutation[l] - ] == ant[0]: + elif self.features[self.permutation[j]].dtype == 'cat': + if antecedent[j] != 'NO': + ant = antecedent[j] + if transactions[i][self.permutation[j]] == ant[0]: match1 = match1 + 1 # secondly consequence @@ -169,19 +158,14 @@ def calculate_support_confidence( len(antecedent), len(antecedent) + len(consequence)): - if self.features[self.permutation[ll] - ].dtype == 'float' or self.features[self.permutation[ll]].dtype == 'int': - if consequence[con_counter] == 'NO': - pass - else: + if self.features[self.permutation[ll]].dtype == 'float' or self.features[self.permutation[ll]].dtype == 'int': + if consequence[con_counter] != 'NO': border = consequence[con_counter] if (float(transactions[i][self.permutation[ll]]) >= border[0]) and ( float(transactions[i][self.permutation[ll]]) <= border[1]): match2 = match2 + 1 elif self.features[self.permutation[ll]].dtype == 'cat': - if consequence[con_counter] == 'NO': - pass - else: + if consequence[con_counter] != 'NO': con = consequence[con_counter] if transactions[i][self.permutation[ll]] == con[0]: @@ -213,26 +197,13 @@ def calculate_support_confidence( return total_supp, total_conf - def check_no(self, antecedent, consequence): - check = True - missing_ant = antecedent.count("NO") - missing_con = consequence.count("NO") - - if missing_ant == len(antecedent): - check = False - - if missing_con == len(consequence): - check = False - - return check - def calculate_coverage(self, antecedent, consequence): missing_ant = antecedent.count("NO") missing_con = consequence.count("NO") missing_total = missing_ant + missing_con - return (1 - float(float(missing_total) / float(len(self.features)))) + return 1 - float(float(missing_total) / float(len(self.features))) def normalize(self, value, actual_bounds, real_bounds): return (real_bounds[0] + @@ -247,29 +218,21 @@ def calculate_shrinkage(self, antecedent, consequence): differences = [] for i in range(len(antecedent)): - if self.features[self.permutation[i] - ].dtype == 'float' or self.features[self.permutation[i]].dtype == 'int': - if antecedent[i] == 'NO': - pass - else: + if self.features[self.permutation[i]].dtype == 'float' or self.features[self.permutation[i]].dtype == 'int': + if antecedent[i] != 'NO': borders = antecedent[i] diff_borders = borders[1] - borders[0] - total_borders = self.features[self.permutation[i] - ].max_val - self.features[self.permutation[i]].min_val + total_borders = self.features[self.permutation[i]].max_val - self.features[self.permutation[i]].min_val diff = float(diff_borders / total_borders) differences.append(diff) con_counter = 0 for ll in range(len(antecedent), len(antecedent) + len(consequence)): - if self.features[self.permutation[ll] - ].dtype == 'float' or self.features[self.permutation[ll]].dtype == 'int': - if consequence[con_counter] == 'NO': - pass - else: + if self.features[self.permutation[ll]].dtype == 'float' or self.features[self.permutation[ll]].dtype == 'int': + if consequence[con_counter] != 'NO': borders = consequence[con_counter] diff_borders = borders[1] - borders[0] - total_borders = self.features[self.permutation[ll] - ].max_val - self.features[self.permutation[ll]].min_val + total_borders = self.features[self.permutation[ll]].max_val - self.features[self.permutation[ll]].min_val diff = float(diff_borders / total_borders) differences.append(diff) con_counter = con_counter + 1 @@ -283,7 +246,7 @@ def calculate_shrinkage(self, antecedent, consequence): else: return 0.0 - return (1 - normalized) + return 1 - normalized def calculate_fitness( self, @@ -302,28 +265,22 @@ def calculate_fitness( def format_rules(self, antecedent, consequence): antecedent1 = [] consequence1 = [] - + for i in range(len(antecedent)): - if antecedent[i] == "NO": - pass - else: + if antecedent[i] != "NO": if self.features[self.permutation[i]].dtype == "cat": rule = self.features[self.permutation[i]].name + "(" + str(antecedent[i][0]) + ")" else: rule = self.features[self.permutation[i]].name + "(" + str(antecedent[i]) + ")" - + antecedent1.append(rule) - for i in range(len(consequence)): - if consequence[i] == "NO": - pass - else: - if self.features[self.permutation[i+len(antecedent)]].dtype == "cat": - rule = self.features[self.permutation[i+len(antecedent)]].name + "(" + str(consequence[i]) + ")" + if consequence[i] != "NO": + if self.features[self.permutation[i + len(antecedent)]].dtype == "cat": + rule = self.features[self.permutation[i + len(antecedent)]].name + "(" + str(consequence[i]) + ")" else: - rule = self.features[self.permutation[i+len(antecedent)]].name + "(" + str(consequence[i]) + ")" - - consequence1.append(rule) + rule = self.features[self.permutation[i + len(antecedent)]].name + "(" + str(consequence[i]) + ")" - return antecedent1, consequence1 + consequence1.append(rule) + return antecedent1, consequence1 diff --git a/niaarm/dataset.py b/niaarm/dataset.py index 8df7281..7430de6 100644 --- a/niaarm/dataset.py +++ b/niaarm/dataset.py @@ -6,42 +6,25 @@ class Dataset: r"""Class for working with dataset. Attributes: - path (str): Path to the dataset. - has_header (Optional(str)): Is header present in csv file. - delimiter (Optional(str)): Delimiter in csv file. - """ + data (pd.DataFrame): Data as a pandas Dataframe. + transactions (np.ndarray): Transactional data. + header (list[str]): Feature names. + features (list[Feature]): List of features. + dimension (int): Dimension of the optimization problem for dataset. - def __init__(self, path, has_header="Yes", delimiter=","): - self.path = path - self.has_header = has_header - self.delimiter = delimiter + """ - self.data = None - self.header = [] + def __init__(self, path, delimiter=',', header=0, names=None): + self.data = pd.read_csv(path, delimiter=delimiter, header=header, names=names) + if names is None and header is None: + self.data.columns = pd.Index([f'Feature{i}' for i in range(len(self.data.columns))]) + self.header = self.data.columns.tolist() + self.transactions = self.data.values self.features = [] + self.__analyse_types() + self.dimension = self.__problem_dimension() - def read_file(self): - r"""Read dataset from file.""" - self.data = pd.read_csv(self.path, sep=self.delimiter) - - def print_raw_output(self): - r"""Print the whole datatable.""" - print(self.data) - - def get_all_column_names(self): - r"""Preprocess all column names.""" - for col in self.data.columns: - self.header.append(col) - - def return_header(self): - r"""Return all column names. - - Returns: - Iterable[any]: list of columns. - """ - return self.header - - def analyse_types(self): + def __analyse_types(self): r"""Extract data types for data in dataset.""" for head in self.header: col = self.data[head] @@ -58,8 +41,7 @@ def analyse_types(self): unique_categories = None else: dtype = "cat" - categories = col.values.tolist() - unique_categories = list(set(categories)) + unique_categories = col.unique() unique_categories.sort(key=str.lower) min_value = None max_value = None @@ -72,25 +54,8 @@ def analyse_types(self): max_value, unique_categories)) - def get_features(self): - r"""Get feature data.""" - self.read_file() - self.get_all_column_names() - self.analyse_types() - - return self.features - - @property - def transaction_data(self): - return self.data.values - - def calculate_dimension_of_individual(self): - r"""Calculate the dimension of the problem. - Dimension of the problem is used in optimization task. - - Returns: - int: dimension - """ + def __problem_dimension(self): + r"""Calculate the dimension of the problem.""" dimension = 0 for feature in self.features: if feature.dtype == "float" or feature.dtype == "int": @@ -102,7 +67,7 @@ def calculate_dimension_of_individual(self): dimension += len(self.features) + 1 return dimension - def get_feature_report(self): + def feature_report(self): r"""Print feature details.""" for feature in self.features: print(feature) diff --git a/niaarm/niaarm.py b/niaarm/niaarm.py index 29486f2..f28836a 100644 --- a/niaarm/niaarm.py +++ b/niaarm/niaarm.py @@ -28,15 +28,12 @@ class NiaARM(Problem): def __init__( self, dimension, - lower, - upper, features, transactions, - alpha, - beta, - gamma, - delta, - output): + alpha=0.0, + beta=0.0, + gamma=0.0, + delta=0.0): r"""Initialize instance of NiaARM. Arguments: @@ -45,15 +42,14 @@ def __init__( self.dim = dimension self.features = features self.transactions = transactions - self.alpha = self.if_criteria_excluded(alpha) - self.beta = self.if_criteria_excluded(beta) - self.gamma = self.if_criteria_excluded(gamma) - self.delta = self.if_criteria_excluded(delta) - self.output = output + self.alpha = alpha + self.beta = beta + self.gamma = gamma + self.delta = delta self.best_fitness = np.NINF self.rules = [] - super().__init__(dimension, lower, upper) + super().__init__(dimension, 0.0, 1.0) def rule_not_exist(self, antecedent, consequence): r"""Check if association rule already exists. @@ -70,19 +66,13 @@ def rule_not_exist(self, antecedent, consequence): return False return True - def if_criteria_excluded(self, criteria): - """In case we do not include specific criteria in final calculation""" - if criteria == None: - criteria = 0.0 - return criteria - def is_border_value_the_same(self, antecedent, consequence): r"""In case lower and upper bounds of interval are the same. We need this in order to provide clean output. Arguments: - antecedent (array): . - consequence (array): . + antecedent (np.ndarray): . + consequence (np.ndarray): . Returns: antecedent (array): @@ -94,7 +84,6 @@ def is_border_value_the_same(self, antecedent, consequence): if antecedent[i][0] == antecedent[i][1]: antecedent[i] = antecedent[i][0] - for i in range(len(consequence)): if len(consequence[i]) > 1: if consequence[i][0] == consequence[i][1]: @@ -102,22 +91,24 @@ def is_border_value_the_same(self, antecedent, consequence): return antecedent, consequence - def rules_to_csv(self): + def rules_to_csv(self, output): r"""Save all association rules found to csv file. """ try: - with open(self.output, 'w', newline='') as f: + with open(output, 'w', newline='') as f: writer = csv.writer(f) - + # write header - writer.writerow(["Antecedent", "Consequence", "Fitness", "Support", "Confidence", "Coverage", "Shrinkage"]) - + writer.writerow( + ["Antecedent", "Consequence", "Fitness", "Support", "Confidence", "Coverage", "Shrinkage"]) + for rule in self.rules: writer.writerow( - [rule.antecedent, rule.consequence, rule.fitness, rule.support, rule.confidence, rule.coverage, rule.shrink]) + [rule.antecedent, rule.consequence, rule.fitness, rule.support, rule.confidence, rule.coverage, + rule.shrink]) except OSError: - print('OSError:', output_file) + print('OSError:', output) else: print("Output successfully") @@ -142,8 +133,7 @@ def _evaluate(self, sol): if arm.is_rule_feasible(antecedent, consequence): # get support and confidence of rule - support, confidence = arm.calculate_support_confidence( - antecedent, consequence, self.transactions) + support, confidence = arm.calculate_support_confidence(antecedent, consequence, self.transactions) if self.gamma == 0.0: shrinkage = 0 @@ -155,21 +145,19 @@ def _evaluate(self, sol): else: coverage = arm.calculate_coverage(antecedent, consequence) - fitness = arm.calculate_fitness(self.alpha, self.beta, self.gamma, self.delta, support, confidence, shrinkage, coverage) - - check_no = arm.check_no(antecedent, consequence) + fitness = arm.calculate_fitness(self.alpha, self.beta, self.gamma, self.delta, support, confidence, + shrinkage, coverage) # in case no attributes were selected for antecedent or consequence - if not check_no: + if antecedent.count("NO") == len(antecedent) or consequence.count("NO") == len(consequence): fitness = 0.0 - - + if support > 0.0 and confidence > 0.0: - + antecedent, consequence = self.is_border_value_the_same(antecedent, consequence) # format rule; remove NO; add name of features antecedent1, consequence1 = arm.format_rules(antecedent, consequence) - + # save feasible rule if self.rule_not_exist(antecedent1, consequence1): self.rules.append( @@ -181,11 +169,12 @@ def _evaluate(self, sol): confidence, coverage, shrinkage - )) + )) if fitness > self.best_fitness: self.best_fitness = fitness - print("Fitness:", fitness, "Support:", support, "Confidence:", confidence, "Coverage:", coverage, "Shrinkage:", shrinkage) + print("Fitness:", fitness, "Support:", support, "Confidence:", confidence, "Coverage:", coverage, + "Shrinkage:", shrinkage) return fitness else: return -1.0 diff --git a/niaarm/stats.py b/niaarm/stats.py index 501a0a2..05b9c0f 100644 --- a/niaarm/stats.py +++ b/niaarm/stats.py @@ -1,6 +1,3 @@ -import math - - class Stats: r"""Class for providing statistical evaluation. @@ -10,35 +7,35 @@ class Stats: def __init__(self, rules): self.rules = rules - + @property def total_rules(self): return len(self.rules) - + @property def avg_fitness(self): - pass - + return + @property def avg_support(self): - pass - + return + @property def avg_consequence(self): - pass - + return + @property def avg_coverage(self): - pass - + return + @property def avg_shrinkage(self): - pass - + return + @property def avg_ant_len(self): - pass - + return + @property def avg_con_len(self): - pass + return diff --git a/niaarm/tests/test_coverage.py b/niaarm/tests/test_coverage.py index 742002a..a5f12df 100644 --- a/niaarm/tests/test_coverage.py +++ b/niaarm/tests/test_coverage.py @@ -9,7 +9,7 @@ class TestCoverage(TestCase): def setUp(self): data = Dataset("datasets/wiki_test_case.csv") - self.features = data.get_features() + self.features = data.features def test_a(self): # Rule: A => 0 diff --git a/niaarm/tests/test_cut_point.py b/niaarm/tests/test_cut_point.py index 826429d..5e19f62 100644 --- a/niaarm/tests/test_cut_point.py +++ b/niaarm/tests/test_cut_point.py @@ -8,7 +8,7 @@ class TestCutPoint(TestCase): # https://en.wikipedia.org/wiki/Lift_(data_mining) def setUp(self): data = Dataset("datasets/wiki_test_case.csv") - self.features = data.get_features() + self.features = data.features self.oper = AssociationRule(self.features) def test_cut_pointA(self): @@ -33,10 +33,11 @@ def test_cut_pointA(self): self.assertEqual(antecedent, [['B']]) self.assertEqual(consequence, ['NO']) + class TestCutPointB(TestCase): def setUp(self): data = Dataset("datasets/Abalone.csv") - self.features = data.get_features() + self.features = data.features self.oper = AssociationRule(self.features) def test_cut_pointB(self): diff --git a/niaarm/tests/test_read_csv.py b/niaarm/tests/test_read_csv.py index fdf66ec..b0650a3 100644 --- a/niaarm/tests/test_read_csv.py +++ b/niaarm/tests/test_read_csv.py @@ -30,11 +30,11 @@ def test_read_features(self): data = Dataset("datasets/Abalone.csv") - features = data.get_features() + features = data.features - individual = data.calculate_dimension_of_individual() + individual = data.dimension - header_a = data.return_header() + header_a = data.header min_value = [] max_value = [] @@ -62,11 +62,11 @@ def test_read_features(self): data = Dataset("datasets/wiki_test_case.csv") - features = data.get_features() + features = data.features - individual = data.calculate_dimension_of_individual() + individual = data.dimension - header_a = data.return_header() + header_a = data.header min_value = [] max_value = [] diff --git a/niaarm/tests/test_rule_building.py b/niaarm/tests/test_rule_building.py index c671060..64e90e7 100644 --- a/niaarm/tests/test_rule_building.py +++ b/niaarm/tests/test_rule_building.py @@ -8,7 +8,7 @@ class TestBuildRuleA(TestCase): # https://en.wikipedia.org/wiki/Lift_(data_mining) def setUp(self): data = Dataset("datasets/wiki_test_case.csv") - self.features = data.get_features() + self.features = data.features self.oper = AssociationRule(self.features) def test_get_permutation(self): @@ -146,7 +146,7 @@ class TestBuildRuleB(TestCase): # Abalone test case def setUp(self): data = Dataset("datasets/Abalone.csv") - self.features = data.get_features() + self.features = data.features self.oper = AssociationRule(self.features) def test_get_permutation(self): diff --git a/niaarm/tests/test_shrinkage.py b/niaarm/tests/test_shrinkage.py index 8baf6a5..88aa340 100644 --- a/niaarm/tests/test_shrinkage.py +++ b/niaarm/tests/test_shrinkage.py @@ -5,7 +5,7 @@ class TestShrinkageA(TestCase): def setUp(self): data = Dataset("datasets/wiki_test_case.csv") - self.features = data.get_features() + self.features = data.features self.oper = AssociationRule(self.features) def test_A(self): diff --git a/niaarm/tests/test_support_confidence.py b/niaarm/tests/test_support_confidence.py index ca6c782..afe6f48 100644 --- a/niaarm/tests/test_support_confidence.py +++ b/niaarm/tests/test_support_confidence.py @@ -9,8 +9,8 @@ class TestSupportConfidence(TestCase): def setUp(self): data = Dataset("datasets/wiki_test_case.csv") - self.features = data.get_features() - self.transactions = data.transaction_data + self.features = data.features + self.transactions = data.transactions def test_a(self): # Rule: A => 0 From d1b07c92bda6aca34f070cccadc3370b0981bf0a Mon Sep 17 00:00:00 2001 From: zStupan Date: Sat, 26 Feb 2022 11:24:12 +0100 Subject: [PATCH 3/5] Refactor --- basic_run.py | 64 +++++++++---------- niaarm/association_rule.py | 84 ++++++++++--------------- niaarm/dataset.py | 12 ++-- niaarm/niaarm.py | 75 +++++++++++----------- niaarm/tests/test_cut_point.py | 17 ++--- niaarm/tests/test_rule_building.py | 20 +++--- niaarm/tests/test_shrinkage.py | 49 ++++++++------- niaarm/tests/test_support_confidence.py | 12 ++-- 8 files changed, 160 insertions(+), 173 deletions(-) diff --git a/basic_run.py b/basic_run.py index e7f35d1..9628a23 100644 --- a/basic_run.py +++ b/basic_run.py @@ -3,37 +3,33 @@ from niapy.algorithms.basic import ParticleSwarmAlgorithm, DifferentialEvolution from niapy.task import Task, OptimizationType -# load and preprocess dataset from csv -data = Dataset("datasets/Abalone.csv") - -# Create a problem::: -# dimension represents dimension of the problem; -# features represent the list of features, while transactions depicts the list of transactions -# the following 4 elements represent weights (support, confidence, coverage, shrinkage) -# None defines that criteria is omitted and is therefore excluded from fitness function -problem = NiaARM(data.dimension, data.features, data.transactions, alpha=1.0, beta=1.0) - -# build niapy task -task = Task( - problem=problem, - max_iters=3, - optimization_type=OptimizationType.MAXIMIZATION) - -# use Differential Evolution (DE) algorithm -# see full list of available algorithms: https://github.com/NiaOrg/NiaPy/blob/master/Algorithms.md -algo = DifferentialEvolution(population_size=50, differential_weight=0.5, crossover_probability=0.9) - -# use Particle swarm Optimization (PSO) algorithm from NiaPy library -algo2 = ParticleSwarmAlgorithm( - population_size=100, - min_velocity=-4.0, - max_velocity=4.0) - -# run algorithm -best = algo.run(task=task) - -# sort rules -problem.sort_rules() - -# export all rules to csv -problem.rules_to_csv('output.csv') + +if __name__ == '__main__': + # load and preprocess dataset from csv + data = Dataset("datasets/Abalone.csv") + + # Create a problem::: + # dimension represents dimension of the problem; + # features represent the list of features, while transactions depicts the list of transactions + # the following 4 elements represent weights (support, confidence, coverage, shrinkage) + # None defines that criteria is omitted and is therefore excluded from fitness function + problem = NiaARM(data.dimension, data.features, data.transactions, alpha=1.0, beta=1.0) + + # build niapy task + task = Task(problem=problem, max_iters=3, optimization_type=OptimizationType.MAXIMIZATION) + + # use Differential Evolution (DE) algorithm + # see full list of available algorithms: https://github.com/NiaOrg/NiaPy/blob/master/Algorithms.md + algo = DifferentialEvolution(population_size=50, differential_weight=0.5, crossover_probability=0.9) + + # use Particle swarm Optimization (PSO) algorithm from NiaPy library + algo2 = ParticleSwarmAlgorithm(population_size=100, min_velocity=-4.0, max_velocity=4.0) + + # run algorithm + best = algo.run(task=task) + + # sort rules + problem.sort_rules() + + # export all rules to csv + problem.export_rules('output.csv') diff --git a/niaarm/association_rule.py b/niaarm/association_rule.py index d52200f..effe4bc 100644 --- a/niaarm/association_rule.py +++ b/niaarm/association_rule.py @@ -1,3 +1,35 @@ +def normalize(value, actual_bounds, real_bounds): + return (real_bounds[0] + + (value - + real_bounds[0]) * + (real_bounds[1] - + real_bounds[0]) / + (actual_bounds[1] - + actual_bounds[0])) + + +def is_rule_feasible(ant, con): + ant_count = ant.count("NO") + con_count = con.count("NO") + if (ant_count == len(ant)) or (con_count == len(con)): + return False + else: + return True + + +def get_cut_point(sol, num_attr): + cut = int(sol * num_attr) + if cut == 0: + cut = 1 + if cut > num_attr - 1: + cut = num_attr - 2 + return cut + + +def get_permutation(s): + return sorted(range(len(s)), key=lambda k: s[k]) + + class AssociationRule: r"""Class for main operations and quality measures. @@ -15,7 +47,7 @@ def build_rule(self, vector): permutation = self.map_permutation(vector) - self.permutation = self.get_permutation(permutation) + self.permutation = get_permutation(permutation) for i in range(len(self.features)): current_feature = self.permutation[i] @@ -81,14 +113,6 @@ def build_rule(self, vector): def map_permutation(self, vector): return vector[-len(self.features):] - def is_rule_feasible(self, ant, con): - ant_count = ant.count("NO") - con_count = con.count("NO") - if (ant_count == len(ant)) or (con_count == len(con)): - return False - else: - return True - def calculate_threshold_move(self, current_feature): if self.features[current_feature].dtype == "float" or self.features[current_feature].dtype == "int": move = 2 @@ -108,23 +132,6 @@ def get_vector_position_of_feature(self, feature): def return_permutation(self): return self.permutation - def get_cut_point(self, sol, num_attr): - cut = int(sol * num_attr) - if cut == 0: - cut = 1 - if cut > num_attr - 1: - cut = num_attr - 2 - return cut - - def get_ant_con(self, rule, cut): - ant = rule[:cut] - con = rule[cut:] - - return ant, con - - def get_permutation(self, s): - return sorted(range(len(s)), key=lambda k: s[k]) - def calculate_support_confidence( self, antecedent, @@ -205,15 +212,6 @@ def calculate_coverage(self, antecedent, consequence): return 1 - float(float(missing_total) / float(len(self.features))) - def normalize(self, value, actual_bounds, real_bounds): - return (real_bounds[0] + - (value - - real_bounds[0]) * - (real_bounds[1] - - real_bounds[0]) / - (actual_bounds[1] - - actual_bounds[0])) - def calculate_shrinkage(self, antecedent, consequence): differences = [] @@ -242,26 +240,12 @@ def calculate_shrinkage(self, antecedent, consequence): value = value + differences[i] if len(differences) > 0: - normalized = self.normalize(value, [0, len(differences)], [0, 1]) + normalized = normalize(value, [0, len(differences)], [0, 1]) else: return 0.0 return 1 - normalized - def calculate_fitness( - self, - alpha, - beta, - gamma, - delta, - support, - confidence, - shrinkage, - coverage): - fitness = ((alpha * support) + (beta * confidence) + (gamma * - shrinkage) + (delta * coverage)) / (alpha + beta + gamma + delta) - return fitness - def format_rules(self, antecedent, consequence): antecedent1 = [] consequence1 = [] diff --git a/niaarm/dataset.py b/niaarm/dataset.py index 7430de6..6fc53ce 100644 --- a/niaarm/dataset.py +++ b/niaarm/dataset.py @@ -29,20 +29,19 @@ def __analyse_types(self): for head in self.header: col = self.data[head] - if col.dtype == "float64": + if col.dtype == "float": dtype = "float" min_value = col.min() max_value = col.max() unique_categories = None - elif col.dtype == "int64": + elif col.dtype == "int": dtype = "int" min_value = col.min() max_value = col.max() unique_categories = None else: dtype = "cat" - unique_categories = col.unique() - unique_categories.sort(key=str.lower) + unique_categories = sorted(col.astype('string').unique().tolist(), key=str.lower) # convert to str just in case min_value = None max_value = None @@ -56,15 +55,12 @@ def __analyse_types(self): def __problem_dimension(self): r"""Calculate the dimension of the problem.""" - dimension = 0 + dimension = len(self.features) + 1 for feature in self.features: if feature.dtype == "float" or feature.dtype == "int": dimension += 3 else: dimension += 2 - - # add dimension for permutation and cut point - dimension += len(self.features) + 1 return dimension def feature_report(self): diff --git a/niaarm/niaarm.py b/niaarm/niaarm.py index f28836a..5e78575 100644 --- a/niaarm/niaarm.py +++ b/niaarm/niaarm.py @@ -1,10 +1,36 @@ from niaarm.rule import Rule -from niaarm.association_rule import AssociationRule +from niaarm.association_rule import AssociationRule, is_rule_feasible, get_cut_point from niapy.problems import Problem import numpy as np import csv +def is_border_value_the_same(antecedent, consequence): + r"""In case lower and upper bounds of interval are the same. + We need this in order to provide clean output. + + Arguments: + antecedent (np.ndarray): . + consequence (np.ndarray): . + + Returns: + antecedent (array): + consequence (array): + """ + + for i in range(len(antecedent)): + if len(antecedent[i]) > 1: + if antecedent[i][0] == antecedent[i][1]: + antecedent[i] = antecedent[i][0] + + for i in range(len(consequence)): + if len(consequence[i]) > 1: + if consequence[i][0] == consequence[i][1]: + consequence[i] = consequence[i][0] + + return antecedent, consequence + + class NiaARM(Problem): r"""Implementation of NiaARM. @@ -39,7 +65,6 @@ def __init__( Arguments: """ - self.dim = dimension self.features = features self.transactions = transactions self.alpha = alpha @@ -66,37 +91,12 @@ def rule_not_exist(self, antecedent, consequence): return False return True - def is_border_value_the_same(self, antecedent, consequence): - r"""In case lower and upper bounds of interval are the same. - We need this in order to provide clean output. - - Arguments: - antecedent (np.ndarray): . - consequence (np.ndarray): . - - Returns: - antecedent (array): - consequence (array): - """ - - for i in range(len(antecedent)): - if len(antecedent[i]) > 1: - if antecedent[i][0] == antecedent[i][1]: - antecedent[i] = antecedent[i][0] - - for i in range(len(consequence)): - if len(consequence[i]) > 1: - if consequence[i][0] == consequence[i][1]: - consequence[i] = consequence[i][0] - - return antecedent, consequence - - def rules_to_csv(self, output): + def export_rules(self, path): r"""Save all association rules found to csv file. """ try: - with open(output, 'w', newline='') as f: + with open(path, 'w', newline='') as f: writer = csv.writer(f) # write header @@ -108,7 +108,7 @@ def rules_to_csv(self, output): [rule.antecedent, rule.consequence, rule.fitness, rule.support, rule.confidence, rule.coverage, rule.shrink]) except OSError: - print('OSError:', output) + print('OSError:', path) else: print("Output successfully") @@ -119,18 +119,19 @@ def _evaluate(self, sol): r"""Evaluate association rule.""" arm = AssociationRule(self.features) - cut_value = sol[self.dim - 1] # get cut point value + cut_value = sol[self.dimension - 1] # get cut point value solution = sol[:-1] # remove cut point - cut = arm.get_cut_point(cut_value, len(self.features)) + cut = get_cut_point(cut_value, len(self.features)) rule = arm.build_rule(solution) # get antecedent and consequence of rule - antecedent, consequence = arm.get_ant_con(rule, cut) + antecedent = rule[:cut] + consequence = rule[cut:] # check if rule is feasible - if arm.is_rule_feasible(antecedent, consequence): + if is_rule_feasible(antecedent, consequence): # get support and confidence of rule support, confidence = arm.calculate_support_confidence(antecedent, consequence, self.transactions) @@ -145,8 +146,8 @@ def _evaluate(self, sol): else: coverage = arm.calculate_coverage(antecedent, consequence) - fitness = arm.calculate_fitness(self.alpha, self.beta, self.gamma, self.delta, support, confidence, - shrinkage, coverage) + fitness = ((self.alpha * support) + (self.beta * confidence) + (self.gamma * shrinkage) + + (self.delta * coverage)) / (self.alpha + self.beta + self.gamma + self.delta) # in case no attributes were selected for antecedent or consequence if antecedent.count("NO") == len(antecedent) or consequence.count("NO") == len(consequence): @@ -154,7 +155,7 @@ def _evaluate(self, sol): if support > 0.0 and confidence > 0.0: - antecedent, consequence = self.is_border_value_the_same(antecedent, consequence) + antecedent, consequence = is_border_value_the_same(antecedent, consequence) # format rule; remove NO; add name of features antecedent1, consequence1 = arm.format_rules(antecedent, consequence) diff --git a/niaarm/tests/test_cut_point.py b/niaarm/tests/test_cut_point.py index 5e19f62..7d62624 100644 --- a/niaarm/tests/test_cut_point.py +++ b/niaarm/tests/test_cut_point.py @@ -1,5 +1,5 @@ from unittest import TestCase -from niaarm.association_rule import AssociationRule +from niaarm.association_rule import AssociationRule, get_cut_point from niaarm.dataset import Dataset @@ -19,12 +19,13 @@ def test_cut_pointA(self): cut_value = sol[len(sol) - 1] new_sol = sol[:-1] - cut = arm.get_cut_point(cut_value, len(self.features)) + cut = get_cut_point(cut_value, len(self.features)) rule = arm.build_rule(new_sol) # get antecedent and consequence of rule - antecedent, consequence = arm.get_ant_con(rule, cut) + antecedent = rule[:cut] + consequence = rule[cut:] self.assertEqual(cut_value, 0.33333333) self.assertEqual(new_sol, [0.98328107, 0.93655004, 0.6860223, 0.78527931, 0.96291945, 0.18117294, 0.50567635]) @@ -122,12 +123,13 @@ def test_cut_pointB(self): new_sol = sol[:-1] - cut = arm.get_cut_point(cut_value, len(self.features)) + cut = get_cut_point(cut_value, len(self.features)) rule = arm.build_rule(new_sol) # get antecedent and consequence of rule - antecedent, consequence = arm.get_ant_con(rule, cut) + antecedent = rule[:cut] + consequence = rule[cut:] self.assertEqual(cut_value, 0.33333333) self.assertEqual(new_sol, new_sol_a) @@ -218,12 +220,13 @@ def test_cut_pointC(self): new_sol = sol[:-1] - cut = arm.get_cut_point(cut_value, len(self.features)) + cut = get_cut_point(cut_value, len(self.features)) rule = arm.build_rule(new_sol) # get antecedent and consequence of rule - antecedent, consequence = arm.get_ant_con(rule, cut) + antecedent = rule[:cut] + consequence = rule[cut:] self.assertEqual(cut_value, 0.53333333) self.assertEqual(new_sol, new_sol_a) diff --git a/niaarm/tests/test_rule_building.py b/niaarm/tests/test_rule_building.py index 64e90e7..00db028 100644 --- a/niaarm/tests/test_rule_building.py +++ b/niaarm/tests/test_rule_building.py @@ -1,5 +1,5 @@ from unittest import TestCase -from niaarm.association_rule import AssociationRule +from niaarm.association_rule import AssociationRule, is_rule_feasible, get_permutation from niaarm.dataset import Dataset @@ -31,27 +31,27 @@ def test_if_feasible_rule(self): consequence_c = ["NO"] self.assertEqual( - self.oper.is_rule_feasible( + is_rule_feasible( antecedent_a, consequence_a), False) self.assertEqual( - self.oper.is_rule_feasible( + is_rule_feasible( antecedent_b, consequence_b), True) self.assertEqual( - self.oper.is_rule_feasible( + is_rule_feasible( antecedent_c, consequence_a), True) self.assertEqual( - self.oper.is_rule_feasible( + is_rule_feasible( antecedent_c, consequence_b), True) self.assertEqual( - self.oper.is_rule_feasible( + is_rule_feasible( antecedent_a, consequence_c), False) @@ -73,7 +73,7 @@ def test_vector_position(self): permutation = self.oper.map_permutation( [0.98328107, 0.93655004, 0.6860223, 0.78527931, 0.96291945, 0.18117294, 0.50567635]) - order = self.oper.get_permutation(permutation) + order = get_permutation(permutation) position1 = self.oper.get_vector_position_of_feature(0) position2 = self.oper.get_vector_position_of_feature(1) @@ -256,7 +256,7 @@ def test_vector_position(self): permutation = self.oper.map_permutation(vector1) - order = self.oper.get_permutation(permutation) + order = get_permutation(permutation) self.assertEqual(order, [1, 3, 5, 4, 8, 7, 2, 6, 0]) @@ -352,7 +352,7 @@ def test_build_rule(self): permutation = self.oper.map_permutation(vector2) - order2 = self.oper.get_permutation(permutation) + order2 = get_permutation(permutation) rule2 = self.oper.build_rule(vector2) @@ -400,7 +400,7 @@ def test_build_rule(self): permutation = self.oper.map_permutation(vector3) - order3 = self.oper.get_permutation(permutation) + order3 = get_permutation(permutation) rule3 = self.oper.build_rule(vector3) diff --git a/niaarm/tests/test_shrinkage.py b/niaarm/tests/test_shrinkage.py index 88aa340..f39724f 100644 --- a/niaarm/tests/test_shrinkage.py +++ b/niaarm/tests/test_shrinkage.py @@ -1,7 +1,8 @@ from unittest import TestCase -from niaarm.association_rule import AssociationRule +from niaarm.association_rule import AssociationRule, normalize, get_cut_point from niaarm.dataset import Dataset + class TestShrinkageA(TestCase): def setUp(self): data = Dataset("datasets/wiki_test_case.csv") @@ -21,11 +22,12 @@ def test_A(self): oper = AssociationRule(self.features) - cut = oper.get_cut_point(0, len(self.features)) + cut = get_cut_point(0, len(self.features)) rule = oper.build_rule(vector) - antecedent, consequence = oper.get_ant_con(rule, cut) + antecedent = rule[:cut] + consequence = rule[cut:] shrinkage = oper.calculate_shrinkage(antecedent, consequence) @@ -52,38 +54,40 @@ def test_B(self): oper = AssociationRule(self.features) - cut = oper.get_cut_point(0, len(self.features)) + cut = get_cut_point(0, len(self.features)) rule = oper.build_rule(vector) - antecedent, consequence = oper.get_ant_con(rule, cut) + antecedent = rule[:cut] + consequence = rule[cut:] shrinkage = oper.calculate_shrinkage(antecedent, consequence) self.assertEqual(shrinkage, 1) + class TestShrinkageB(TestCase): - #Rule == - #Ant: ['Diameter([0.34108412769999996, 0.56784007355])', 'Viscera weight([0.13678483190000001, 0.44964727704])'] - #Con: ['Length([0.2620357326, 0.4989950842])'] + # Rule == + # Ant: ['Diameter([0.34108412769999996, 0.56784007355])', 'Viscera weight([0.13678483190000001, 0.44964727704])'] + # Con: ['Length([0.2620357326, 0.4989950842])'] - #n1 = 0.56784007355 - 0.34108412769999996 = 0.22675594585000004 - #n1a = 0.65 - 0.055 = 0.595 - #n1f = n1 / n1a = 0.22675594585000004 / 0.595 = 0.38110243 + # n1 = 0.56784007355 - 0.34108412769999996 = 0.22675594585000004 + # n1a = 0.65 - 0.055 = 0.595 + # n1f = n1 / n1a = 0.22675594585000004 / 0.595 = 0.38110243 - #n2 = 0.44964727704 - 0.13678483190000001 = 0.31286244513999999 - #n2a = 0.76 - 0.0005 = 0.7595 - #n2f = 0.31286244513999999 / 0.7595 = 0.41193212 + # n2 = 0.44964727704 - 0.13678483190000001 = 0.31286244513999999 + # n2a = 0.76 - 0.0005 = 0.7595 + # n2f = 0.31286244513999999 / 0.7595 = 0.41193212 - #n3 = 0.4989950842 - 0.2620357326 = 0.2369593516 - #n3a = 0.815 - 0.075 = 0.740 - #n3f = 0.2369593516 / 0.740 = 0.32021534 + # n3 = 0.4989950842 - 0.2620357326 = 0.2369593516 + # n3a = 0.815 - 0.075 = 0.740 + # n3f = 0.2369593516 / 0.740 = 0.32021534 - #val = n1f + n2f + n3f = 0.38110243 + 0.41193212 + 0.32021534 = 1.11324989 + # val = n1f + n2f + n3f = 0.38110243 + 0.41193212 + 0.32021534 = 1.11324989 def setUp(self): data = Dataset("datasets/Abalone.csv") - self.features = data.get_features() + self.features = data.features self.oper = AssociationRule(self.features) def test_get_permutation(self): @@ -131,16 +135,17 @@ def test_get_permutation(self): cut_value = vector1[len(vector1) - 1] new_sol = vector1[:-1] - cut = oper.get_cut_point(cut_value, len(self.features)) + cut = get_cut_point(cut_value, len(self.features)) rule = oper.build_rule(new_sol) # get antecedent and consequence of rule - antecedent, consequence = oper.get_ant_con(rule, cut) + antecedent = rule[:cut] + consequence = rule[cut:] shrinkage = oper.calculate_shrinkage(antecedent, consequence) - norm = oper.normalize(1.11324989, [0, 3], [0, 1]) + norm = normalize(1.11324989, [0, 3], [0, 1]) self.assertEqual(norm, 0.3710832966666667) self.assertEqual(shrinkage, 0.6289167033333334) diff --git a/niaarm/tests/test_support_confidence.py b/niaarm/tests/test_support_confidence.py index afe6f48..d77c9dd 100644 --- a/niaarm/tests/test_support_confidence.py +++ b/niaarm/tests/test_support_confidence.py @@ -1,5 +1,5 @@ from unittest import TestCase -from niaarm.association_rule import AssociationRule +from niaarm.association_rule import AssociationRule, get_cut_point from niaarm.dataset import Dataset @@ -33,11 +33,12 @@ def test_a(self): oper = AssociationRule(self.features) - cut = oper.get_cut_point(0, len(self.features)) + cut = get_cut_point(0, len(self.features)) rule = oper.build_rule(vector) - antecedent, consequence = oper.get_ant_con(rule, cut) + antecedent = rule[:cut] + consequence = rule[cut:] support, confidence = oper.calculate_support_confidence( antecedent, consequence, self.transactions) @@ -68,11 +69,12 @@ def test_B(self): oper = AssociationRule(self.features) - cut = oper.get_cut_point(0, len(self.features)) + cut = get_cut_point(0, len(self.features)) rule = oper.build_rule(vector) - antecedent, consequence = oper.get_ant_con(rule, cut) + antecedent = rule[:cut] + consequence = rule[cut:] support, confidence = oper.calculate_support_confidence( antecedent, consequence, self.transactions) From c96fae04583d2a9b519182cb6cd4c7ebd0700cce Mon Sep 17 00:00:00 2001 From: zStupan Date: Sat, 26 Feb 2022 11:55:26 +0100 Subject: [PATCH 4/5] Refactor --- basic_run.py | 9 +++------ niaarm/niaarm.py | 13 ++++++------- 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/basic_run.py b/basic_run.py index 9628a23..9508fc2 100644 --- a/basic_run.py +++ b/basic_run.py @@ -1,6 +1,6 @@ from niaarm import NiaARM from niaarm.dataset import Dataset -from niapy.algorithms.basic import ParticleSwarmAlgorithm, DifferentialEvolution +from niapy.algorithms.basic import DifferentialEvolution from niapy.task import Task, OptimizationType @@ -16,15 +16,12 @@ problem = NiaARM(data.dimension, data.features, data.transactions, alpha=1.0, beta=1.0) # build niapy task - task = Task(problem=problem, max_iters=3, optimization_type=OptimizationType.MAXIMIZATION) + task = Task(problem=problem, max_iters=30, optimization_type=OptimizationType.MAXIMIZATION) - # use Differential Evolution (DE) algorithm + # use Differential Evolution (DE) algorithm from the NiaPy library # see full list of available algorithms: https://github.com/NiaOrg/NiaPy/blob/master/Algorithms.md algo = DifferentialEvolution(population_size=50, differential_weight=0.5, crossover_probability=0.9) - # use Particle swarm Optimization (PSO) algorithm from NiaPy library - algo2 = ParticleSwarmAlgorithm(population_size=100, min_velocity=-4.0, max_velocity=4.0) - # run algorithm best = algo.run(task=task) diff --git a/niaarm/niaarm.py b/niaarm/niaarm.py index 5e78575..a19c9f5 100644 --- a/niaarm/niaarm.py +++ b/niaarm/niaarm.py @@ -76,7 +76,7 @@ def __init__( self.rules = [] super().__init__(dimension, 0.0, 1.0) - def rule_not_exist(self, antecedent, consequence): + def rule_exists(self, antecedent, consequence): r"""Check if association rule already exists. Arguments: antecedent (array): . @@ -85,11 +85,10 @@ def rule_not_exist(self, antecedent, consequence): Returns: None """ - for i in range(len(self.rules)): - if ((self.rules[i].antecedent == antecedent) and ( - self.rules[i].consequence == consequence)): - return False - return True + for rule in self.rules: + if rule.antecedent == antecedent and rule.consequence == consequence: + return True + return False def export_rules(self, path): r"""Save all association rules found to csv file. @@ -160,7 +159,7 @@ def _evaluate(self, sol): antecedent1, consequence1 = arm.format_rules(antecedent, consequence) # save feasible rule - if self.rule_not_exist(antecedent1, consequence1): + if not self.rule_exists(antecedent1, consequence1): self.rules.append( Rule( antecedent1, From 03d57a3ebcfb72ecac8abcd324dee4d41cb69abf Mon Sep 17 00:00:00 2001 From: zStupan Date: Sat, 26 Feb 2022 12:15:12 +0100 Subject: [PATCH 5/5] Implemented Stats class --- niaarm/stats.py | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/niaarm/stats.py b/niaarm/stats.py index 05b9c0f..965df44 100644 --- a/niaarm/stats.py +++ b/niaarm/stats.py @@ -1,3 +1,6 @@ +import numpy as np + + class Stats: r"""Class for providing statistical evaluation. @@ -14,28 +17,28 @@ def total_rules(self): @property def avg_fitness(self): - return + return np.mean([rule.fitness for rule in self.rules]) @property def avg_support(self): - return + return np.mean([rule.support for rule in self.rules]) @property - def avg_consequence(self): - return + def avg_confidence(self): + return np.mean([rule.confidence for rule in self.rules]) @property def avg_coverage(self): - return + return np.mean([rule.coverage for rule in self.rules]) @property def avg_shrinkage(self): - return + return np.mean([rule.shrink for rule in self.rules]) @property def avg_ant_len(self): - return + return np.mean([len(rule.antecedent) for rule in self.rules]) @property def avg_con_len(self): - return + return np.mean([len(rule.consequence) for rule in self.rules])