diff --git a/data/data-pipeline/data_pipeline/etl/sources/census_acs/etl.py b/data/data-pipeline/data_pipeline/etl/sources/census_acs/etl.py index dba9d06b..e7cd5e96 100644 --- a/data/data-pipeline/data_pipeline/etl/sources/census_acs/etl.py +++ b/data/data-pipeline/data_pipeline/etl/sources/census_acs/etl.py @@ -619,16 +619,6 @@ class CensusACSETL(ExtractTransformLoad): lower=0 ) - # All values should have a value at this point - assert ( - df[ - self.ADJUSTED_AND_IMPUTED_POVERTY_LESS_THAN_200_PERCENT_FPL_FIELD_NAME - ] - .isna() - .sum() - == 0 - ), "Error: not all values were filled..." - logger.info("Renaming columns...") df = df.rename( columns={ diff --git a/data/data-pipeline/data_pipeline/etl/sources/census_acs/etl_imputations.py b/data/data-pipeline/data_pipeline/etl/sources/census_acs/etl_imputations.py index 17180026..692ac243 100644 --- a/data/data-pipeline/data_pipeline/etl/sources/census_acs/etl_imputations.py +++ b/data/data-pipeline/data_pipeline/etl/sources/census_acs/etl_imputations.py @@ -1,6 +1,7 @@ -from typing import Any, List, NamedTuple, Tuple import pandas as pd import geopandas as gpd +from data_pipeline.score.field_names import GEOID_TRACT_FIELD +import numpy as np from data_pipeline.utils import get_module_logger @@ -9,53 +10,15 @@ from data_pipeline.utils import get_module_logger logger = get_module_logger(__name__) -def _get_fips_mask( - geo_df: gpd.GeoDataFrame, - row: gpd.GeoSeries, - fips_digits: int, - geoid_field: str = "GEOID10_TRACT", -) -> pd.Series: - return ( - geo_df[geoid_field].str[:fips_digits] == row[geoid_field][:fips_digits] - ) - - -def _get_neighbor_mask( - geo_df: gpd.GeoDataFrame, row: gpd.GeoSeries -) -> pd.Series: - return geo_df["geometry"].touches(row["geometry"]) - - -def _choose_best_mask( - geo_df: gpd.GeoDataFrame, - masks_in_priority_order: List[pd.Series], - column_to_impute: str, -) -> pd.Series: - for mask in masks_in_priority_order: - if any(geo_df[mask][column_to_impute].notna()): - return mask - raise Exception("No mask found") - - def _prepare_dataframe_for_imputation( - impute_var_named_tup_list: List[NamedTuple], + columns_to_impute: list, geo_df: gpd.GeoDataFrame, geoid_field: str = "GEOID10_TRACT", -) -> Tuple[Any, gpd.GeoDataFrame]: - imputing_cols = [ - impute_var_pair.raw_field_name - for impute_var_pair in impute_var_named_tup_list - ] - - # prime column to exist - for impute_var_pair in impute_var_named_tup_list: - geo_df[impute_var_pair.imputed_field_name] = geo_df[ - impute_var_pair.raw_field_name - ].copy() +): # generate a list of tracts for which at least one of the imputation # columns is null - tract_list = geo_df[geo_df[imputing_cols].isna().any(axis=1)][ + tract_list = geo_df[geo_df[columns_to_impute].isna().any(axis=1)][ geoid_field ].unique() @@ -66,15 +29,36 @@ def _prepare_dataframe_for_imputation( return tract_list, geo_df +def _get_state_and_county_fills(df, tract_list, impute_var_pair_list): + # When there is no neighbor average, we take the county-level average or state-level averages + for impute_var_pair in impute_var_pair_list: + # Fill missings with county means + df[impute_var_pair.imputed_field_name] = np.where( + (df[impute_var_pair.imputed_field_name].isna()) + & (df[GEOID_TRACT_FIELD].isin(tract_list)), + df.groupby(df[GEOID_TRACT_FIELD].str[:5])[ + impute_var_pair.raw_field_name + ].transform(np.mean), + df[impute_var_pair.imputed_field_name], + ) + # Fill the remaining missings with state means + df[impute_var_pair.imputed_field_name] = np.where( + (df[impute_var_pair.imputed_field_name].isna()) + & (df[GEOID_TRACT_FIELD].isin(tract_list)), + df.groupby(df[GEOID_TRACT_FIELD].str[:2])[ + impute_var_pair.raw_field_name + ].transform(np.mean), + df[impute_var_pair.imputed_field_name], + ) + return df + + def calculate_income_measures( impute_var_named_tup_list: list, geo_df: gpd.GeoDataFrame, geoid_field: str, ) -> pd.DataFrame: - """Impute values based on geographic neighbors - - We only want to check neighbors a single time, so all variables - that we impute get imputed here. + """Impute values based on geographic neighbors or county fields. Takes in: required: @@ -84,50 +68,58 @@ def calculate_income_measures( Returns: non-geometry pd.DataFrame """ + + raw_fields = [] + imputed_fields = [] + rename_dict = {} + for impute_var in impute_var_named_tup_list: + raw_fields.append(impute_var.raw_field_name) + imputed_fields.append(impute_var.imputed_field_name) + + assert ( + impute_var.raw_field_name not in rename_dict + ), f"Error: trying to impute {impute_var.raw_field_name} twice" + rename_dict[impute_var.raw_field_name] = impute_var.imputed_field_name + # Determine where to impute variables and fill a column with nulls tract_list, geo_df = _prepare_dataframe_for_imputation( - impute_var_named_tup_list=impute_var_named_tup_list, + columns_to_impute=raw_fields, geo_df=geo_df, geoid_field=geoid_field, ) - # Iterate through the dataframe to impute in place - ## TODO: We should probably convert this to a spatial join now that we are doing >1 imputation and it's taking a lot - ## of time, but thinking through how to do this while maintaining the masking will take some time. I think the best - ## way would be to (1) spatial join to all neighbors, and then (2) iterate to take the "smallest" set of neighbors... - ## but haven't implemented it yet. - for index, row in geo_df.iterrows(): - if row[geoid_field] in tract_list: - neighbor_mask = _get_neighbor_mask(geo_df, row) - county_mask = _get_fips_mask( - geo_df=geo_df, row=row, fips_digits=5, geoid_field=geoid_field - ) - ## TODO: Did CEQ decide to cut this? - state_mask = _get_fips_mask( - geo_df=geo_df, row=row, fips_digits=2, geoid_field=geoid_field - ) + missing_tracts_df = geo_df[geo_df[GEOID_TRACT_FIELD].isin(tract_list)] - # Impute fields for every row missing at least one value using the best possible set of neighbors - # Note that later, we will pull raw.fillna(imputed), so the mechanics of this step aren't critical - for impute_var_pair in impute_var_named_tup_list: - mask_to_use = _choose_best_mask( - geo_df=geo_df, - masks_in_priority_order=[ - neighbor_mask, - county_mask, - state_mask, - ], - column_to_impute=impute_var_pair.raw_field_name, - ) - geo_df.loc[index, impute_var_pair.imputed_field_name] = geo_df[ - mask_to_use - ][impute_var_pair.raw_field_name].mean() + # Perform as spatial merge to save time + spatially_joined_df = missing_tracts_df[ + [GEOID_TRACT_FIELD, "geometry"] + ].sjoin( + geo_df[raw_fields + ["geometry"]], + predicate="touches", + ) - logger.info("Casting geodataframe as a typical dataframe") + # First take the neighbor averages + neighbor_averages_df = ( + spatially_joined_df.groupby(GEOID_TRACT_FIELD)[raw_fields] + .mean() + .reset_index() + .rename(columns=rename_dict) + ) + + logger.info("Merging and casting geodataframe as a typical dataframe") # get rid of the geometry column and cast as a typical df df = pd.DataFrame( - geo_df[[col for col in geo_df.columns if col != "geometry"]] + geo_df[[col for col in geo_df.columns if col != "geometry"]].merge( + neighbor_averages_df, + on=[GEOID_TRACT_FIELD], + how="outer", + ) ) + logger.info(df.head()) + + logger.info("Filling with county or state") + df = _get_state_and_county_fills(df, tract_list, impute_var_named_tup_list) + logger.info(df.head()) # finally, return the df return df diff --git a/data/data-pipeline/data_pipeline/etl/sources/geo_utils.py b/data/data-pipeline/data_pipeline/etl/sources/geo_utils.py index 87ce119f..ddb9fd70 100644 --- a/data/data-pipeline/data_pipeline/etl/sources/geo_utils.py +++ b/data/data-pipeline/data_pipeline/etl/sources/geo_utils.py @@ -6,6 +6,7 @@ from functools import lru_cache import geopandas as gpd from data_pipeline.utils import get_module_logger from .census.etl import CensusETL +from data_pipeline.score import field_names logger = get_module_logger(__name__) @@ -27,7 +28,9 @@ def get_tract_geojson( else: logger.debug("Loading existing tract geojson") tract_data = gpd.read_file(GEOJSON_PATH, include_fields=["GEOID10"]) - tract_data.rename(columns={"GEOID10": "GEOID10_TRACT"}, inplace=True) + tract_data.rename( + columns={"GEOID10": field_names.GEOID_TRACT_FIELD}, inplace=True + ) return tract_data @@ -55,7 +58,7 @@ def add_tracts_for_geometries( ), f"Dataframe must be projected to {tract_data.crs}" df = gpd.sjoin( df, - tract_data[["GEOID10_TRACT", "geometry"]], + tract_data[[field_names.GEOID_TRACT_FIELD, "geometry"]], how="inner", op="intersects", ) diff --git a/data/data-pipeline/poetry.lock b/data/data-pipeline/poetry.lock index b7e685fb..d778c20e 100644 --- a/data/data-pipeline/poetry.lock +++ b/data/data-pipeline/poetry.lock @@ -67,16 +67,19 @@ tests = ["pytest"] [[package]] name = "astroid" -version = "2.11.7" +version = "2.12.5" description = "An abstract syntax tree for Python with inference support." category = "main" optional = false -python-versions = ">=3.6.2" +python-versions = ">=3.7.2" [package.dependencies] lazy-object-proxy = ">=1.4.0" typing-extensions = {version = ">=3.10", markers = "python_version < \"3.10\""} -wrapt = ">=1.11,<2" +wrapt = [ + {version = ">=1.11,<2", markers = "python_version < \"3.11\""}, + {version = ">=1.14,<2", markers = "python_version >= \"3.11\""}, +] [[package]] name = "atomicwrites" @@ -209,7 +212,7 @@ pycparser = "*" [[package]] name = "charset-normalizer" -version = "2.1.0" +version = "2.1.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." category = "main" optional = false @@ -267,15 +270,15 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" [[package]] name = "configparser" -version = "5.2.0" -description = "Updated configparser from Python 3.8 for Python 2.6+." +version = "5.3.0" +description = "Updated configparser from stdlib for earlier Pythons." category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" [package.extras] -docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)", "jaraco.tidelift (>=1.4)"] -testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "types-backports", "pytest-black (>=0.3.7)", "pytest-mypy"] +docs = ["sphinx", "jaraco.packaging (>=9)", "rst.linker (>=1.9)", "jaraco.tidelift (>=1.4)"] +testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "flake8 (<5)", "pytest-cov", "pytest-enabler (>=1.3)", "types-backports", "pytest-black (>=0.3.7)", "pytest-mypy (>=0.9.1)"] [[package]] name = "cycler" @@ -322,7 +325,7 @@ graph = ["objgraph (>=1.7.2)"] [[package]] name = "distlib" -version = "0.3.5" +version = "0.3.6" description = "Distribution utilities" category = "dev" optional = false @@ -439,7 +442,7 @@ pyflakes = ">=2.3.0,<2.4.0" [[package]] name = "fonttools" -version = "4.35.0" +version = "4.37.1" description = "Tools to manipulate font files" category = "main" optional = false @@ -486,7 +489,7 @@ python-versions = ">=3.5" name = "importlib-metadata" version = "4.12.0" description = "Read metadata from Python packages" -category = "dev" +category = "main" optional = false python-versions = ">=3.7" @@ -536,7 +539,7 @@ toml = {version = ">=0.10.2", markers = "python_version > \"3.6\""} [[package]] name = "ipykernel" -version = "6.15.1" +version = "6.15.2" description = "IPython Kernel for Jupyter" category = "main" optional = false @@ -556,7 +559,7 @@ tornado = ">=6.1" traitlets = ">=5.1.0" [package.extras] -test = ["pytest (>=6.0)", "pytest-timeout", "pytest-cov", "pre-commit", "ipyparallel", "flaky"] +test = ["flaky", "ipyparallel", "pre-commit", "pytest-cov", "pytest-timeout", "pytest (>=6.0)"] [[package]] name = "ipython" @@ -600,22 +603,21 @@ python-versions = "*" [[package]] name = "ipywidgets" -version = "7.7.1" -description = "IPython HTML widgets for Jupyter" +version = "8.0.1" +description = "Jupyter interactive widgets" category = "main" optional = false -python-versions = "*" +python-versions = ">=3.7" [package.dependencies] ipykernel = ">=4.5.1" -ipython = {version = ">=4.0.0", markers = "python_version >= \"3.3\""} -ipython-genutils = ">=0.2.0,<0.3.0" -jupyterlab-widgets = {version = ">=1.0.0", markers = "python_version >= \"3.6\""} +ipython = ">=6.1.0" +jupyterlab-widgets = ">=3.0,<4.0" traitlets = ">=4.3.1" -widgetsnbextension = ">=3.6.0,<3.7.0" +widgetsnbextension = ">=4.0,<5.0" [package.extras] -test = ["mock", "pytest-cov", "pytest (>=3.6.0)"] +test = ["jsonschema", "pytest (>=3.6.0)", "pytest-cov", "pytz"] [[package]] name = "isort" @@ -670,7 +672,7 @@ i18n = ["Babel (>=2.7)"] [[package]] name = "json5" -version = "0.9.9" +version = "0.9.10" description = "A Python implementation of the JSON5 data format." category = "dev" optional = false @@ -681,7 +683,7 @@ dev = ["hypothesis"] [[package]] name = "jsonschema" -version = "4.10.0" +version = "4.15.0" description = "An implementation of JSON Schema validation for Python" category = "main" optional = false @@ -715,7 +717,7 @@ qtconsole = "*" [[package]] name = "jupyter-client" -version = "7.3.4" +version = "7.3.5" description = "Jupyter protocol implementation and client libraries" category = "main" optional = false @@ -727,12 +729,12 @@ jupyter-core = ">=4.9.2" nest-asyncio = ">=1.5.4" python-dateutil = ">=2.8.2" pyzmq = ">=23.0" -tornado = ">=6.0" +tornado = ">=6.2" traitlets = "*" [package.extras] -test = ["pytest-timeout", "pytest-cov", "pytest-asyncio (>=0.18)", "pytest", "pre-commit", "mypy", "ipython", "ipykernel (>=6.5)", "coverage", "codecov"] -doc = ["sphinxcontrib-github-alt", "sphinx (>=1.3.6)", "sphinx-rtd-theme", "myst-parser", "ipykernel"] +doc = ["ipykernel", "myst-parser", "sphinx-rtd-theme", "sphinx (>=1.3.6)", "sphinxcontrib-github-alt"] +test = ["codecov", "coverage", "ipykernel (>=6.5)", "ipython", "mypy", "pre-commit", "pytest", "pytest-asyncio (>=0.18)", "pytest-cov", "pytest-timeout"] [[package]] name = "jupyter-console" @@ -913,7 +915,7 @@ python-versions = ">=3.7" [[package]] name = "jupyterlab-server" -version = "2.15.0" +version = "2.15.1" description = "A set of server components for JupyterLab and JupyterLab like applications." category = "dev" optional = false @@ -935,11 +937,11 @@ test = ["codecov", "ipykernel", "jupyter-server", "openapi-core (>=0.14.2)", "op [[package]] name = "jupyterlab-widgets" -version = "1.1.1" -description = "A JupyterLab extension." +version = "3.0.2" +description = "Jupyter interactive widgets for JupyterLab" category = "main" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" [[package]] name = "kiwisolver" @@ -994,7 +996,7 @@ python-versions = ">=3.7" [[package]] name = "marshmallow" -version = "3.17.0" +version = "3.17.1" description = "A lightweight library for converting complex datatypes to and from native Python datatypes." category = "main" optional = false @@ -1004,9 +1006,9 @@ python-versions = ">=3.7" packaging = ">=17.0" [package.extras] -dev = ["pytest", "pytz", "simplejson", "mypy (==0.961)", "flake8 (==4.0.1)", "flake8-bugbear (==22.6.22)", "pre-commit (>=2.4,<3.0)", "tox"] -docs = ["sphinx (==4.5.0)", "sphinx-issues (==3.0.1)", "alabaster (==0.7.12)", "sphinx-version-warning (==1.1.2)", "autodocsumm (==0.2.8)"] -lint = ["mypy (==0.961)", "flake8 (==4.0.1)", "flake8-bugbear (==22.6.22)", "pre-commit (>=2.4,<3.0)"] +dev = ["pytest", "pytz", "simplejson", "mypy (==0.971)", "flake8 (==5.0.4)", "flake8-bugbear (==22.8.22)", "pre-commit (>=2.4,<3.0)", "tox"] +docs = ["sphinx (==5.1.1)", "sphinx-issues (==3.0.1)", "alabaster (==0.7.12)", "sphinx-version-warning (==1.1.2)", "autodocsumm (==0.2.9)"] +lint = ["mypy (==0.971)", "flake8 (==5.0.4)", "flake8-bugbear (==22.8.22)", "pre-commit (>=2.4,<3.0)"] tests = ["pytest", "pytz", "simplejson"] [[package]] @@ -1061,7 +1063,7 @@ setuptools_scm = ">=4,<7" [[package]] name = "matplotlib-inline" -version = "0.1.3" +version = "0.1.6" description = "Inline Matplotlib backend for Jupyter" category = "main" optional = false @@ -1080,8 +1082,8 @@ python-versions = "*" [[package]] name = "mistune" -version = "0.8.4" -description = "The fastest markdown parser in pure Python" +version = "2.0.4" +description = "A sane Markdown parser with useful plugins and renderers" category = "main" optional = false python-versions = "*" @@ -1171,7 +1173,7 @@ docs = ["myst-parser", "sphinx-rtd-theme", "sphinxcontrib-github-alt", "nbsphinx [[package]] name = "nbclient" -version = "0.6.6" +version = "0.6.7" description = "A client library for executing notebooks. Formerly nbconvert's ExecutePreprocessor." category = "main" optional = false @@ -1185,11 +1187,11 @@ traitlets = ">=5.2.2" [package.extras] sphinx = ["autodoc-traits", "mock", "moto", "myst-parser", "Sphinx (>=1.7)", "sphinx-book-theme"] -test = ["black", "check-manifest", "flake8", "ipykernel", "ipython (<8.0.0)", "ipywidgets (<8.0.0)", "mypy", "pip (>=18.1)", "pre-commit", "pytest (>=4.1)", "pytest-asyncio", "pytest-cov (>=2.6.1)", "setuptools (>=60.0)", "testpath", "twine (>=1.11.0)", "xmltodict"] +test = ["black", "check-manifest", "flake8", "ipykernel", "ipython", "ipywidgets", "mypy", "nbconvert", "pip (>=18.1)", "pre-commit", "pytest (>=4.1)", "pytest-asyncio", "pytest-cov (>=2.6.1)", "setuptools (>=60.0)", "testpath", "twine (>=1.11.0)", "xmltodict"] [[package]] name = "nbconvert" -version = "6.5.3" +version = "7.0.0" description = "Converting Jupyter Notebooks" category = "main" optional = false @@ -1199,13 +1201,13 @@ python-versions = ">=3.7" beautifulsoup4 = "*" bleach = "*" defusedxml = "*" -entrypoints = ">=0.2.2" +importlib-metadata = {version = ">=3.6", markers = "python_version < \"3.10\""} jinja2 = ">=3.0" jupyter-core = ">=4.7" jupyterlab-pygments = "*" lxml = "*" -MarkupSafe = ">=2.0" -mistune = ">=0.8.1,<2" +markupsafe = ">=2.0" +mistune = ">=2.0.3,<3" nbclient = ">=0.5.0" nbformat = ">=5.1" packaging = "*" @@ -1215,10 +1217,12 @@ tinycss2 = "*" traitlets = ">=5.0" [package.extras] -all = ["pytest", "pytest-cov", "pytest-dependency", "ipykernel", "ipywidgets (>=7)", "pre-commit", "pyppeteer (>=1,<1.1)", "tornado (>=6.1)", "sphinx (>=1.5.1)", "sphinx-rtd-theme", "nbsphinx (>=0.2.12)", "ipython"] -docs = ["sphinx (>=1.5.1)", "sphinx-rtd-theme", "nbsphinx (>=0.2.12)", "ipython"] +all = ["ipykernel", "ipython", "ipywidgets (>=7)", "nbsphinx (>=0.2.12)", "pre-commit", "pyppeteer (>=1,<1.1)", "pyqtwebengine (>=5.15)", "pytest", "pytest-cov", "pytest-dependency", "sphinx-rtd-theme", "sphinx (==5.0.2)", "tornado (>=6.1)"] +docs = ["ipython", "nbsphinx (>=0.2.12)", "sphinx-rtd-theme", "sphinx (==5.0.2)"] +qtpdf = ["pyqtwebengine (>=5.15)"] +qtpng = ["pyqtwebengine (>=5.15)"] serve = ["tornado (>=6.1)"] -test = ["pytest", "pytest-cov", "pytest-dependency", "ipykernel", "ipywidgets (>=7)", "pre-commit", "pyppeteer (>=1,<1.1)"] +test = ["ipykernel", "ipywidgets (>=7)", "pre-commit", "pyppeteer (>=1,<1.1)", "pytest", "pytest-cov", "pytest-dependency"] webpdf = ["pyppeteer (>=1,<1.1)"] [[package]] @@ -1322,7 +1326,7 @@ pyparsing = ">=2.0.2,<3.0.5 || >3.0.5" [[package]] name = "pandas" -version = "1.4.3" +version = "1.4.4" description = "Powerful data structures for data analysis, time series, and statistics" category = "main" optional = false @@ -1330,16 +1334,16 @@ python-versions = ">=3.8" [package.dependencies] numpy = [ - {version = ">=1.21.0", markers = "python_version >= \"3.10\""}, - {version = ">=1.20.0", markers = "platform_machine == \"arm64\" and python_version < \"3.10\""}, - {version = ">=1.19.2", markers = "platform_machine == \"aarch64\" and python_version < \"3.10\""}, {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 = ["pytest-xdist (>=1.31)", "pytest (>=6.0)", "hypothesis (>=5.5.3)"] +test = ["hypothesis (>=5.5.3)", "pytest (>=6.0)", "pytest-xdist (>=1.31)"] [[package]] name = "pandas-vet" @@ -1405,11 +1409,11 @@ testing = ["docopt", "pytest (<6.0.0)"] [[package]] name = "pathspec" -version = "0.9.0" +version = "0.10.0" description = "Utility library for gitignore style pattern matching of file paths." category = "dev" optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" +python-versions = ">=3.7" [[package]] name = "pexpect" @@ -1537,14 +1541,14 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [[package]] name = "pydantic" -version = "1.9.2" +version = "1.10.1" description = "Data validation and settings management using python type hints" category = "main" optional = false -python-versions = ">=3.6.1" +python-versions = ">=3.7" [package.dependencies] -typing-extensions = ">=3.7.4.3" +typing-extensions = ">=4.1.0" [package.extras] dotenv = ["python-dotenv (>=0.10.4)"] @@ -1571,14 +1575,14 @@ plugins = ["importlib-metadata"] [[package]] name = "pylint" -version = "2.14.5" +version = "2.15.0" description = "python code static checker" category = "main" optional = false python-versions = ">=3.7.2" [package.dependencies] -astroid = ">=2.11.6,<=2.12.0-dev0" +astroid = ">=2.12.4,<=2.14.0-dev0" colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""} dill = ">=0.2" isort = ">=4.2.5,<6" @@ -1733,7 +1737,7 @@ py = {version = "*", markers = "implementation_name == \"pypy\""} [[package]] name = "qtconsole" -version = "5.3.1" +version = "5.3.2" description = "Jupyter Qt console" category = "main" optional = false @@ -1750,8 +1754,8 @@ qtpy = ">=2.0.1" traitlets = "<5.2.1 || >5.2.1,<5.2.2 || >5.2.2" [package.extras] -test = ["pytest-qt", "pytest", "flaky"] doc = ["Sphinx (>=1.3)"] +test = ["flaky", "pytest", "pytest-qt"] [[package]] name = "qtpy" @@ -1875,7 +1879,7 @@ toml = ["setuptools (>=42)"] [[package]] name = "shapely" -version = "1.8.2" +version = "1.8.4" description = "Geometric objects, predicates, and operations" category = "main" optional = false @@ -2059,7 +2063,7 @@ test = ["pytest", "pre-commit"] [[package]] name = "types-requests" -version = "2.28.8" +version = "2.28.9" description = "Typing stubs for requests" category = "main" optional = false @@ -2070,7 +2074,7 @@ types-urllib3 = "<1.27" [[package]] name = "types-urllib3" -version = "1.26.22" +version = "1.26.23" description = "Typing stubs for urllib3" category = "main" optional = false @@ -2086,7 +2090,7 @@ python-versions = ">=3.7" [[package]] name = "typing-inspect" -version = "0.7.1" +version = "0.8.0" description = "Runtime inspection utilities for typing module." category = "main" optional = false @@ -2098,16 +2102,16 @@ typing-extensions = ">=3.7.4" [[package]] name = "urllib3" -version = "1.26.11" +version = "1.26.12" description = "HTTP library with thread-safe connection pooling, file post, and more." category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, <4" [package.extras] +brotli = ["brotlicffi (>=0.8.0)", "brotli (>=1.0.9)", "brotlipy (>=0.6.0)"] +secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "urllib3-secure-extra", "ipaddress"] socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] -secure = ["ipaddress", "certifi", "idna (>=2.0.0)", "cryptography (>=1.3.4)", "pyOpenSSL (>=0.14)"] -brotli = ["brotlipy (>=0.6.0)", "brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] [[package]] name = "us" @@ -2122,7 +2126,7 @@ jellyfish = "0.6.1" [[package]] name = "virtualenv" -version = "20.16.3" +version = "20.16.4" description = "Virtual Python Environment builder" category = "dev" optional = false @@ -2155,27 +2159,24 @@ python-versions = "*" [[package]] name = "websocket-client" -version = "1.3.3" +version = "1.4.0" description = "WebSocket client for Python with low level API options" category = "dev" optional = false python-versions = ">=3.7" [package.extras] -docs = ["Sphinx (>=3.4)", "sphinx-rtd-theme (>=0.5)"] -optional = ["python-socks", "wsaccel"] test = ["websockets"] +optional = ["wsaccel", "python-socks"] +docs = ["sphinx-rtd-theme (>=0.5)", "Sphinx (>=3.4)"] [[package]] name = "widgetsnbextension" -version = "3.6.1" -description = "IPython HTML widgets for Jupyter" +version = "4.0.2" +description = "Jupyter interactive widgets for Jupyter Notebook" category = "main" optional = false -python-versions = "*" - -[package.dependencies] -notebook = ">=4.4.1" +python-versions = ">=3.7" [[package]] name = "wrapt" @@ -2283,10 +2284,7 @@ cligj = [ {file = "cligj-0.7.2.tar.gz", hash = "sha256:a4bc13d623356b373c2c27c53dbd9c68cae5d526270bfa71f6c6fa69669c6b27"}, ] colorama = [] -configparser = [ - {file = "configparser-5.2.0-py3-none-any.whl", hash = "sha256:e8b39238fb6f0153a069aa253d349467c3c4737934f253ef6abac5fe0eca1e5d"}, - {file = "configparser-5.2.0.tar.gz", hash = "sha256:1b35798fdf1713f1c3139016cfcbc461f09edbf099d1fb658d4b7479fcaa3daa"}, -] +configparser = [] cycler = [ {file = "cycler-0.11.0-py3-none-any.whl", hash = "sha256:3a27e95f763a428a739d2add979fa7494c912a32c17c4c38c4d5f082cad165a3"}, {file = "cycler-0.11.0.tar.gz", hash = "sha256:9c87405839a19696e837b3b818fed3f5f69f16f1eec1a1ad77e043dcea9c772f"}, @@ -2490,18 +2488,12 @@ marshmallow-enum = [ {file = "marshmallow_enum-1.5.1-py2.py3-none-any.whl", hash = "sha256:57161ab3dbfde4f57adeb12090f39592e992b9c86d206d02f6bd03ebec60f072"}, ] matplotlib = [] -matplotlib-inline = [ - {file = "matplotlib-inline-0.1.3.tar.gz", hash = "sha256:a04bfba22e0d1395479f866853ec1ee28eea1485c1d69a6faf00dc3e24ff34ee"}, - {file = "matplotlib_inline-0.1.3-py3-none-any.whl", hash = "sha256:aed605ba3b72462d64d475a21a9296f400a19c4f74a31b59103d2a99ffd5aa5c"}, -] +matplotlib-inline = [] mccabe = [ {file = "mccabe-0.6.1-py2.py3-none-any.whl", hash = "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42"}, {file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"}, ] -mistune = [ - {file = "mistune-0.8.4-py2.py3-none-any.whl", hash = "sha256:88a1051873018da288eee8538d476dffe1262495144b33ecb586c4ab266bb8d4"}, - {file = "mistune-0.8.4.tar.gz", hash = "sha256:59a3429db53c50b5c6bcc8a07f8848cb00d7dc8bdb431a4ab41920d201d4756e"}, -] +mistune = [] munch = [ {file = "munch-2.5.0-py2.py3-none-any.whl", hash = "sha256:6f44af89a2ce4ed04ff8de41f70b226b984db10a91dcc7b9ac2efc1c77022fdd"}, {file = "munch-2.5.0.tar.gz", hash = "sha256:2d735f6f24d4dba3417fa448cae40c6e896ec1fdab6cdb5e6510999758a4dbd2"}, @@ -2568,10 +2560,7 @@ parso = [ {file = "parso-0.8.3-py2.py3-none-any.whl", hash = "sha256:c001d4636cd3aecdaf33cbb40aebb59b094be2a74c556778ef5576c175e19e75"}, {file = "parso-0.8.3.tar.gz", hash = "sha256:8c07be290bb59f03588915921e29e8a50002acaf2cdc5fa0e0114f91709fafa0"}, ] -pathspec = [ - {file = "pathspec-0.9.0-py2.py3-none-any.whl", hash = "sha256:7d15c4ddb0b5c802d161efc417ec1a2558ea2653c2e8ad9c19098201dc1c993a"}, - {file = "pathspec-0.9.0.tar.gz", hash = "sha256:e564499435a2673d586f6b2130bb5b95f04a3ba06f81b8f895b651a3c76aabb1"}, -] +pathspec = [] pexpect = [ {file = "pexpect-4.8.0-py2.py3-none-any.whl", hash = "sha256:0b48a55dcb3c05f3329815901ea4fc1537514d6ba867a152b581d69ae3710937"}, {file = "pexpect-4.8.0.tar.gz", hash = "sha256:fc65a43959d153d0114afe13997d439c22823a27cefceb5ff35c2178c6784c0c"}, @@ -2845,11 +2834,7 @@ traitlets = [] types-requests = [] types-urllib3 = [] typing-extensions = [] -typing-inspect = [ - {file = "typing_inspect-0.7.1-py2-none-any.whl", hash = "sha256:b1f56c0783ef0f25fb064a01be6e5407e54cf4a4bf4f3ba3fe51e0bd6dcea9e5"}, - {file = "typing_inspect-0.7.1-py3-none-any.whl", hash = "sha256:3cd7d4563e997719a710a3bfe7ffb544c6b72069b6812a02e9b414a8fa3aaa6b"}, - {file = "typing_inspect-0.7.1.tar.gz", hash = "sha256:047d4097d9b17f46531bf6f014356111a1b6fb821a24fe7ac909853ca2a782aa"}, -] +typing-inspect = [] urllib3 = [] us = [ {file = "us-2.0.2.tar.gz", hash = "sha256:cb11ad0d43deff3a1c3690c74f0c731cff5b862c73339df2edd91133e1496fbc"},