From a7e7f1ddbb0d006da04c703ce7b8421539aae605 Mon Sep 17 00:00:00 2001 From: PyMap Date: Fri, 17 Jul 2020 17:39:59 -0300 Subject: [PATCH 01/12] Include PUMS2018 records Combine the use of pums files that include years prior to 2010 (puma00) from aws and that do not (only puma10) from gcs --- synthpop/census_helpers.py | 22 ++++++++++++++++------ synthpop/recipes/starter.py | 15 ++++++++++++--- synthpop/recipes/starter2.py | 14 +++++++++++--- 3 files changed, 39 insertions(+), 12 deletions(-) diff --git a/synthpop/census_helpers.py b/synthpop/census_helpers.py index 3b04825..430aa9d 100644 --- a/synthpop/census_helpers.py +++ b/synthpop/census_helpers.py @@ -6,15 +6,23 @@ # code to retry when census api fails sess = requests.Session() -adapter = requests.adapters.HTTPAdapter(max_retries = 100) +adapter = requests.adapters.HTTPAdapter(max_retries=100) sess.mount('https://', adapter) # TODO DOCSTRING!! + + class Census: - def __init__(self, key): - self.c = census.Census(key, session = sess) - self.base_url = "https://s3-us-west-1.amazonaws.com/synthpop-data2/" + def __init__(self, key, acsyear): + self.c = census.Census(key, session=sess) + + if acsyear >= 2018: + storage = "https://storage.googleapis.com/synthpop-public/PUMS2018/pums_2018_acs5/" + else: + storage = "https://s3-us-west-1.amazonaws.com/synthpop-data2/" + self.base_url = storage + self.acsyear_files = acsyear self.pums_relationship_file_url = self.base_url + "tract10_to_puma.csv" self.pums_relationship_df = None self.pums10_population_base_url = \ @@ -180,7 +188,8 @@ def download_population_pums(self, state, puma10=None, puma00=None, **kargs): if (puma10 is None) & (puma00 is None): return self._read_csv(self.pums_population_state_base_url % (state), **kargs) pums = self._read_csv(self.pums10_population_base_url % (state, puma10), **kargs) - if puma00 is not None: + if (puma00 is not None) & (self.acsyear_files < 2018): + print('Reading PUMS00 from %s' % (self.base_url)) pums00 = self._read_csv(self.pums00_population_base_url % (state, puma00), **kargs) pums = pd.concat([pums, pums00], ignore_index=True) return pums @@ -190,7 +199,8 @@ def download_household_pums(self, state, puma10=None, puma00=None, **kargs): if (puma10 is None) & (puma00 is None): return self._read_csv(self.pums_household_state_base_url % (state), **kargs) pums = self._read_csv(self.pums10_household_base_url % (state, puma10), **kargs) - if puma00 is not None: + if (puma00 is not None) & (self.acsyear_files < 2018): + print('Reading PUMS00 from %s' % (self.base_url)) pums00 = self._read_csv(self.pums00_household_base_url % (state, puma00), **kargs) pums = pd.concat([pums, pums00], ignore_index=True) diff --git a/synthpop/recipes/starter.py b/synthpop/recipes/starter.py index ba61140..0814072 100644 --- a/synthpop/recipes/starter.py +++ b/synthpop/recipes/starter.py @@ -38,8 +38,9 @@ class Starter: tract_to_puma_map : dictionary keys are tract ids and pumas are puma ids """ + def __init__(self, key, state, county, tract=None, acsyear=2016): - self.c = c = Census(key) + self.c = c = Census(key, acsyear) self.state = state self.county = county self.tract = tract @@ -117,9 +118,17 @@ def __init__(self, key, state, county, tract=None, acsyear=2016): # Put the needed PUMS variables here. These are also the PUMS variables # that will be in the outputted synthetic population - self.h_pums_cols = ('serialno', 'PUMA00', 'PUMA10', 'RT', 'NP', + self.h_pums_cols = ('serialno', 'PUMA10', 'RT', 'NP', 'TYPE', 'VEH', 'WIF', 'NOC', 'FINCP') - self.p_pums_cols = ('serialno', 'PUMA00', 'PUMA10', 'AGEP', 'RAC1P', 'SEX') + self.p_pums_cols = ('serialno', 'PUMA10', 'AGEP', 'RAC1P', 'SEX') + + if self.acsyear < 2018: + self.h_pums_cols = list(self.h_pums_cols) + self.h_pums_cols.insert(1, 'PUMA00') + self.h_pums_cols = tuple(self.h_pums_cols) + self.p_pums_cols = list(self.p_pums_cols) + self.p_pums_cols.insert(1, 'PUMA00') + self.p_pums_cols = tuple(self.p_pums_cols) def get_geography_name(self): # this synthesis is at the block group level for most variables diff --git a/synthpop/recipes/starter2.py b/synthpop/recipes/starter2.py index 8008d9e..6826dda 100644 --- a/synthpop/recipes/starter2.py +++ b/synthpop/recipes/starter2.py @@ -42,8 +42,9 @@ class Starter: tract_to_puma_map : dictionary keys are tract ids and pumas are puma ids """ + def __init__(self, key, state, county, tract=None, acsyear=2016): - self.c = c = Census(key) + self.c = c = Census(key, acsyear) self.state = state self.county = county self.tract = tract @@ -179,11 +180,18 @@ def __init__(self, key, state, county, tract=None, acsyear=2016): # Put the needed PUMS variables here. These are also the PUMS variables # that will be in the outputted synthetic population - self.h_pums_cols = ('serialno', 'PUMA00', 'PUMA10', 'RT', 'NP', 'TYPE', + self.h_pums_cols = ('serialno', 'PUMA10', 'RT', 'NP', 'TYPE', 'R65', 'HINCP', 'VEH', 'MV', 'TEN', 'BLD', 'R18') - self.p_pums_cols = ('serialno', 'PUMA00', 'PUMA10', 'RELP', 'AGEP', + self.p_pums_cols = ('serialno', 'PUMA10', 'RELP', 'AGEP', 'ESR', 'RAC1P', 'HISP', 'SEX', 'SPORDER', 'PERNP', 'SCHL', 'WKHP', 'JWTR', 'SCH') + if self.acsyear < 2018: + self.h_pums_cols = list(self.h_pums_cols) + self.h_pums_cols.insert(1, 'PUMA00') + self.h_pums_cols = tuple(self.h_pums_cols) + self.p_pums_cols = list(self.p_pums_cols) + self.p_pums_cols.insert(1, 'PUMA00') + self.p_pums_cols = tuple(self.p_pums_cols) def get_geography_name(self): # this synthesis is at the block group level for most variables From 0442357e5c3ca4969f185ed3bf6ed87af8d73562 Mon Sep 17 00:00:00 2001 From: PyMap Date: Mon, 20 Jul 2020 15:25:31 -0300 Subject: [PATCH 02/12] Improvement for Travis tests Add default acsyear for Census constructor + informative prints --- synthpop/census_helpers.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/synthpop/census_helpers.py b/synthpop/census_helpers.py index 430aa9d..806f09a 100644 --- a/synthpop/census_helpers.py +++ b/synthpop/census_helpers.py @@ -14,7 +14,7 @@ class Census: - def __init__(self, key, acsyear): + def __init__(self, key, acsyear=2013): self.c = census.Census(key, session=sess) if acsyear >= 2018: @@ -184,6 +184,7 @@ def _read_csv(self, loc, **kargs): return self.pums_cache[loc] def download_population_pums(self, state, puma10=None, puma00=None, **kargs): + print('Downloading population pums from %s' % (self.base_url)) state = self.try_fips_lookup(state) if (puma10 is None) & (puma00 is None): return self._read_csv(self.pums_population_state_base_url % (state), **kargs) @@ -195,6 +196,7 @@ def download_population_pums(self, state, puma10=None, puma00=None, **kargs): return pums def download_household_pums(self, state, puma10=None, puma00=None, **kargs): + print('Downloading households pums from %s' % (self.base_url)) state = self.try_fips_lookup(state) if (puma10 is None) & (puma00 is None): return self._read_csv(self.pums_household_state_base_url % (state), **kargs) From 9da497fd8dcc31fc505a1833f95c54fc2a66a118 Mon Sep 17 00:00:00 2001 From: PyMap Date: Mon, 20 Jul 2020 15:30:21 -0300 Subject: [PATCH 03/12] Change 2013 for 2016 in Census() 2016 is the default acsyear in starter and starter2 --- synthpop/census_helpers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/synthpop/census_helpers.py b/synthpop/census_helpers.py index 806f09a..5db0fc2 100644 --- a/synthpop/census_helpers.py +++ b/synthpop/census_helpers.py @@ -14,7 +14,7 @@ class Census: - def __init__(self, key, acsyear=2013): + def __init__(self, key, acsyear=2016): self.c = census.Census(key, session=sess) if acsyear >= 2018: From 737912b175bc697ec53d9a6888989725ebd07fed Mon Sep 17 00:00:00 2001 From: PyMap Date: Wed, 22 Jul 2020 11:52:55 -0300 Subject: [PATCH 04/12] Explanation notebook with all synthesis steps --- demos/Synthesis workflow.ipynb | 1568 ++++++++++++++++++++++++++++++++ 1 file changed, 1568 insertions(+) create mode 100644 demos/Synthesis workflow.ipynb diff --git a/demos/Synthesis workflow.ipynb b/demos/Synthesis workflow.ipynb new file mode 100644 index 0000000..1c2d7b5 --- /dev/null +++ b/demos/Synthesis workflow.ipynb @@ -0,0 +1,1568 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "from fpdf import FPDF\n", + "import seaborn as sns\n", + "import matplotlib.pyplot as plt\n", + "import pandas as pd\n", + "import numpy as np\n", + "import os\n", + "import sys\n", + "import argparse\n", + "\n", + "from synthpop.recipes.starter2 import Starter\n", + "from synthpop.census_helpers import Census\n", + "import warnings\n", + "warnings.filterwarnings('ignore')\n", + "\n", + "sns.set()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Synthesis flow" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "DIAGRAM 0 HERE: synthesize all" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 1.1. What we are postprocessing?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "DEFINITION HERE: ESTO ES LO QUE VAMOS A ANALIZAR, PERO QUE SIGNIFICA? REPRESENTA ALGO EN PARTICULAR? COMO SE INTERPRETA ESTA TABLA?" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "def postprocess(state, county, year, path):\n", + " hh = pd.read_csv(path + '/hh_{}_{}_{}.csv'.\n", + " format(state, county, year), dtype={'serialno': 'str',\n", + " 'block_id': 'str',\n", + " 'state': 'str',\n", + " 'county': 'str',\n", + " 'tract': 'str',\n", + " 'block_group': 'str'})\n", + " hh.rename(columns={'Unnamed: 0': 'household_id'}, inplace=True)\n", + " hh.set_index('household_id', inplace=True)\n", + "\n", + " p = pd.read_csv(path + '/p_{}_{}_{}.csv'.\n", + " format(state, county, year), dtype={'serialno': 'str', })\n", + " p.rename(columns={'Unnamed: 0': 'person_id', 'hh_id': 'household_id'}, inplace=True)\n", + " p.set_index('person_id', inplace=True)\n", + "\n", + " # Format persons\n", + " p.rename(columns={'AGEP': 'age', 'RAC1P': 'race_id', 'NP': 'persons', 'SPORDER': 'member_id',\n", + " 'RELP': 'relate', 'SEX': 'sex', 'WKHP': 'hours', 'SCHL': 'edu', 'PERNP': 'earning'},\n", + " inplace=True)\n", + " return hh, p" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "02_290.pdf \u001b[0m\u001b[01;32mhh_02_195_2013.csv\u001b[0m* \u001b[01;32mp_02_110_2013.csv\u001b[0m*\r\n", + "\u001b[01;32mhh_02_013_2013.csv\u001b[0m* \u001b[01;32mhh_02_198_2013.csv\u001b[0m* \u001b[01;32mp_02_122_2013.csv\u001b[0m*\r\n", + "\u001b[01;32mhh_02_016_2013.csv\u001b[0m* \u001b[01;32mhh_02_220_2013.csv\u001b[0m* \u001b[01;32mp_02_130_2013.csv\u001b[0m*\r\n", + "\u001b[01;32mhh_02_020_2013.csv\u001b[0m* \u001b[01;32mhh_02_230_2013.csv\u001b[0m* \u001b[01;32mp_02_150_2013.csv\u001b[0m*\r\n", + "\u001b[01;32mhh_02_050_2013.csv\u001b[0m* \u001b[01;32mhh_02_240_2013.csv\u001b[0m* \u001b[01;32mp_02_164_2013.csv\u001b[0m*\r\n", + "\u001b[01;32mhh_02_060_2013.csv\u001b[0m* \u001b[01;32mhh_02_261_2013.csv\u001b[0m* \u001b[01;32mp_02_170_2013.csv\u001b[0m*\r\n", + "\u001b[01;32mhh_02_068_2013.csv\u001b[0m* \u001b[01;32mhh_02_270_2013.csv\u001b[0m* \u001b[01;32mp_02_180_2013.csv\u001b[0m*\r\n", + "\u001b[01;32mhh_02_070_2013.csv\u001b[0m* \u001b[01;32mhh_02_275_2013.csv\u001b[0m* \u001b[01;32mp_02_185_2013.csv\u001b[0m*\r\n", + "\u001b[01;32mhh_02_090_2013.csv\u001b[0m* \u001b[01;32mhh_02_282_2013.csv\u001b[0m* \u001b[01;32mp_02_188_2013.csv\u001b[0m*\r\n", + "\u001b[01;32mhh_02_100_2013.csv\u001b[0m* \u001b[01;32mhh_02_290_2013.csv\u001b[0m* \u001b[01;32mp_02_195_2013.csv\u001b[0m*\r\n", + "\u001b[01;32mhh_02_105_2013.csv\u001b[0m* \u001b[01;32mp_02_013_2013.csv\u001b[0m* \u001b[01;32mp_02_198_2013.csv\u001b[0m*\r\n", + "\u001b[01;32mhh_02_110_2013.csv\u001b[0m* \u001b[01;32mp_02_016_2013.csv\u001b[0m* \u001b[01;32mp_02_220_2013.csv\u001b[0m*\r\n", + "\u001b[01;32mhh_02_122_2013.csv\u001b[0m* \u001b[01;32mp_02_020_2013.csv\u001b[0m* \u001b[01;32mp_02_230_2013.csv\u001b[0m*\r\n", + "\u001b[01;32mhh_02_130_2013.csv\u001b[0m* \u001b[01;32mp_02_050_2013.csv\u001b[0m* \u001b[01;32mp_02_240_2013.csv\u001b[0m*\r\n", + "\u001b[01;32mhh_02_150_2013.csv\u001b[0m* \u001b[01;32mp_02_060_2013.csv\u001b[0m* \u001b[01;32mp_02_261_2013.csv\u001b[0m*\r\n", + "\u001b[01;32mhh_02_164_2013.csv\u001b[0m* \u001b[01;32mp_02_068_2013.csv\u001b[0m* \u001b[01;32mp_02_270_2013.csv\u001b[0m*\r\n", + "\u001b[01;32mhh_02_170_2013.csv\u001b[0m* \u001b[01;32mp_02_070_2013.csv\u001b[0m* \u001b[01;32mp_02_275_2013.csv\u001b[0m*\r\n", + "\u001b[01;32mhh_02_180_2013.csv\u001b[0m* \u001b[01;32mp_02_090_2013.csv\u001b[0m* \u001b[01;32mp_02_282_2013.csv\u001b[0m*\r\n", + "\u001b[01;32mhh_02_185_2013.csv\u001b[0m* \u001b[01;32mp_02_100_2013.csv\u001b[0m* \u001b[01;32mp_02_290_2013.csv\u001b[0m*\r\n", + "\u001b[01;32mhh_02_188_2013.csv\u001b[0m* \u001b[01;32mp_02_105_2013.csv\u001b[0m*\r\n" + ] + } + ], + "source": [ + "# Here we have a list of synthesized counties for hh and p from the 02 (AK) state\n", + "ls 02/" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "# These files looks like...\n", + "hh, p = postprocess('02', '013', 2013, '02/')" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
serialnoRTpuma00puma10NPTYPEBLDTENVEHHINCP...hh_sizehh_workersseniorssf_detachedtenure_movercat_idstatecountytractblock group
household_id
02012000184237H-9400112.04.01.032500.0...oneonenoyesrent not recent19334020130001001
12012000184237H-9400112.04.01.032500.0...oneonenoyesrent not recent19334020130001001
22013000404401H-9400112.03.02.033000.0...oneonenoyesrent not recent34694020130001001
\n", + "

3 rows × 32 columns

\n", + "
" + ], + "text/plain": [ + " serialno RT puma00 puma10 NP TYPE BLD TEN VEH \\\n", + "household_id \n", + "0 2012000184237 H -9 400 1 1 2.0 4.0 1.0 \n", + "1 2012000184237 H -9 400 1 1 2.0 4.0 1.0 \n", + "2 2013000404401 H -9 400 1 1 2.0 3.0 2.0 \n", + "\n", + " HINCP ... hh_size hh_workers seniors sf_detached \\\n", + "household_id ... \n", + "0 32500.0 ... one one no yes \n", + "1 32500.0 ... one one no yes \n", + "2 33000.0 ... one one no yes \n", + "\n", + " tenure_mover cat_id state county tract block group \n", + "household_id \n", + "0 rent not recent 19334 02 013 000100 1 \n", + "1 rent not recent 19334 02 013 000100 1 \n", + "2 rent not recent 34694 02 013 000100 1 \n", + "\n", + "[3 rows x 32 columns]" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "hh.head(3)" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
serialnomember_idpuma00puma10ageJWTRrelateSCHedusex...ESRHISPearningrace_idhispanicperson_ageperson_sexracecat_idhousehold_id
person_id
020120001842371-94004312.001.016.01...1.0131000.04no35 to 60maleother1382620
120120001842371-94004312.001.016.01...1.0131000.04no35 to 60maleother1382621
220120002004751-9400391.001.019.01...1.0143300.09no35 to 60maleother1382628
\n", + "

3 rows × 21 columns

\n", + "
" + ], + "text/plain": [ + " serialno member_id puma00 puma10 age JWTR relate SCH \\\n", + "person_id \n", + "0 2012000184237 1 -9 400 43 12.0 0 1.0 \n", + "1 2012000184237 1 -9 400 43 12.0 0 1.0 \n", + "2 2012000200475 1 -9 400 39 1.0 0 1.0 \n", + "\n", + " edu sex ... ESR HISP earning race_id hispanic person_age \\\n", + "person_id ... \n", + "0 16.0 1 ... 1.0 1 31000.0 4 no 35 to 60 \n", + "1 16.0 1 ... 1.0 1 31000.0 4 no 35 to 60 \n", + "2 19.0 1 ... 1.0 1 43300.0 9 no 35 to 60 \n", + "\n", + " person_sex race cat_id household_id \n", + "person_id \n", + "0 male other 138262 0 \n", + "1 male other 138262 1 \n", + "2 male other 138262 8 \n", + "\n", + "[3 rows x 21 columns]" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "p.head(3)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 1.2. What does these tables represent? " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Starter " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "DIAGRAM HERE: how Starter is instantiated" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Getting `marginals` and `joint distributions` for households and persons " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 1. The `acs5` subject table " + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [], + "source": [ + "# census api key\n", + "key = os.environ['CENSUS']\n", + "\n", + "# AK state\n", + "state = '02'\n", + "\n", + "# 290 county (Yukon-Koyukuk)\n", + "county = '290'" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [], + "source": [ + "# creates starter object\n", + "starter = Starter(key, state, county, acsyear=2013)" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "['acsyear', 'c', 'county', 'get_available_geography_ids', 'get_geography_name', 'get_household_joint_dist_for_geography', 'get_household_marginal_for_geography', 'get_num_geographies', 'get_person_joint_dist_for_geography', 'get_person_marginal_for_geography', 'h_acs', 'h_acs_cat', 'h_pums_cols', 'p_acs', 'p_acs_cat', 'p_pums_cols', 'state', 'tract']\n" + ] + } + ], + "source": [ + "# what do we get from starter class?\n", + "print([m for m in dir(starter) if not m.startswith('__')])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This contains a bunch of methods and variables for a synthesized:" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "('02', '290')" + ] + }, + "execution_count": 31, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# ...state and county pair\n", + "starter.state, starter.county" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "##### 1. 1. The `Census` object and his methods " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " A. Tract and Block group acs subject tables\n", + "\n", + " DIAGRAM 1 HERE" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "As it is shown in the diagram, a first step that occurs when we create the `starter` object is that methods from `Census` constructor are also instantiated. This gives us back some relevant information. First, the `acs` 5 years [estimates tables](https://www.census.gov/data/developers/data-sets/acs-5year.html) by different geographies:" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
NAMEB19001_001EB19001_002EB19001_003EB19001_004EB19001_005EB19001_006EB19001_007EB19001_008EB19001_009E...B08201_002EB08201_003EB08201_004EB08201_005EB08201_006EB08202_001EB08202_002EB08202_003EB08202_004EB08202_005E
0Block Group 1, Census Tract 1, Yukon-Koyukuk C...187521320112012118...1194016371878974212
1Block Group 2, Census Tract 1, Yukon-Koyukuk C...33668194220112789...2147130513336160133373
\n", + "

2 rows × 127 columns

\n", + "
" + ], + "text/plain": [ + " NAME B19001_001E \\\n", + "0 Block Group 1, Census Tract 1, Yukon-Koyukuk C... 187 \n", + "1 Block Group 2, Census Tract 1, Yukon-Koyukuk C... 336 \n", + "\n", + " B19001_002E B19001_003E B19001_004E B19001_005E B19001_006E \\\n", + "0 52 13 20 11 20 \n", + "1 68 19 42 20 11 \n", + "\n", + " B19001_007E B19001_008E B19001_009E ... B08201_002E B08201_003E \\\n", + "0 12 1 18 ... 119 40 \n", + "1 27 8 9 ... 214 71 \n", + "\n", + " B08201_004E B08201_005E B08201_006E B08202_001E B08202_002E \\\n", + "0 16 3 7 187 89 \n", + "1 30 5 13 336 160 \n", + "\n", + " B08202_003E B08202_004E B08202_005E \n", + "0 74 21 2 \n", + "1 133 37 3 \n", + "\n", + "[2 rows x 127 columns]" + ] + }, + "execution_count": 34, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "starter.h_acs.head(2)" + ] + }, + { + "cell_type": "code", + "execution_count": 105, + "metadata": {}, + "outputs": [], + "source": [ + "# when we instantiate the Starter class to create starter object we are also creating a census object\n", + "c = Census(key, acsyear=2013)" + ] + }, + { + "cell_type": "code", + "execution_count": 104, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 104, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "starter.c " + ] + }, + { + "cell_type": "code", + "execution_count": 49, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 49, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "c" + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "['_get_fips_lookup', '_get_pums_relationship', '_query', '_read_csv', '_scale_and_merge', 'acsyear_files', 'base_url', 'block_group_and_tract_query', 'block_group_query', 'c', 'download_household_pums', 'download_population_pums', 'fips_df', 'fips_url', 'pums00_household_base_url', 'pums00_population_base_url', 'pums10_household_base_url', 'pums10_population_base_url', 'pums_cache', 'pums_household_state_base_url', 'pums_population_state_base_url', 'pums_relationship_df', 'pums_relationship_file_url', 'tract_query', 'tract_to_puma', 'try_fips_lookup']\n" + ] + } + ], + "source": [ + "# that has his own methods \n", + "print([ m for m in dir(c) if not m.startswith('__')])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "##### 1. 2. Articulating `Census` and `Starter` methods\n", + "\n", + "As we said, a first thing that takes place when creating `starter` is the generation of `block groups` and `tracts` tables for a [group of variables](https://github.com/UDST/synthpop/blob/0bc36f8fef036913b416e0d4eb8a3fda79fc70ad/synthpop/recipes/starter2.py#L52-L68)" + ] + }, + { + "cell_type": "code", + "execution_count": 106, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + ">" + ] + }, + "execution_count": 106, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# we create and merge both tables with:\n", + "c.block_group_and_tract_query" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In the above diagram it is shown that, inside the `Starter` class some methods from census object `c` are called. But something else to be pointed out here is that, this last one `c` is also calling other methods from `census` module. \n", + "\n", + "We are interested in the `acs5` method - which is inside the core.py module imported from `import census` module -. Let's check it:" + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "['ALL', '_acs', 'acs', 'acs1', 'acs1dp', 'acs3', 'acs3dp', 'acs5', 'acs5dp', 'session', 'sf1', 'sf3']\n" + ] + } + ], + "source": [ + "# imported methods from census module\n", + "print([ m for m in dir(c.c) if not m.startswith('__')])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now, we will define some arbitrary variables at block group and tract levels to consume `acs5` subject tables" + ] + }, + { + "cell_type": "code", + "execution_count": 107, + "metadata": {}, + "outputs": [], + "source": [ + "# block group\n", + "presence_of_children_columns = ['B11005_001E', 'B11005_002E', 'B11005_011E']\n", + "block_group_size_attr=['B11005_001E'] # this is the total within the block group\n", + "\n", + "# census tract\n", + "vehicle_columns = ['B08201_0%02dE' % i for i in range(1, 7)]\n", + "tract_size_attr=['B08201_001E'] # this is the total within the tract" + ] + }, + { + "cell_type": "code", + "execution_count": 99, + "metadata": {}, + "outputs": [], + "source": [ + "tr = c.c.acs5.get(['NAME'] + presence_of_children_columns,\n", + " geo={'for': \"tract:*\",\n", + " 'in': 'state: 02 county: 290'}, year=2013)" + ] + }, + { + "cell_type": "code", + "execution_count": 100, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
NAMEB11005_001EB11005_002EB11005_011Estatecountytract
0Census Tract 1, Yukon-Koyukuk Census Area, Alaska523.0140.0383.002290000100
1Census Tract 2, Yukon-Koyukuk Census Area, Alaska549.0155.0394.002290000200
2Census Tract 3, Yukon-Koyukuk Census Area, Alaska612.0251.0361.002290000300
3Census Tract 4, Yukon-Koyukuk Census Area, Alaska372.0151.0221.002290000400
\n", + "
" + ], + "text/plain": [ + " NAME B11005_001E \\\n", + "0 Census Tract 1, Yukon-Koyukuk Census Area, Alaska 523.0 \n", + "1 Census Tract 2, Yukon-Koyukuk Census Area, Alaska 549.0 \n", + "2 Census Tract 3, Yukon-Koyukuk Census Area, Alaska 612.0 \n", + "3 Census Tract 4, Yukon-Koyukuk Census Area, Alaska 372.0 \n", + "\n", + " B11005_002E B11005_011E state county tract \n", + "0 140.0 383.0 02 290 000100 \n", + "1 155.0 394.0 02 290 000200 \n", + "2 251.0 361.0 02 290 000300 \n", + "3 151.0 221.0 02 290 000400 " + ] + }, + "execution_count": 100, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pd.DataFrame(tr)" + ] + }, + { + "cell_type": "code", + "execution_count": 76, + "metadata": {}, + "outputs": [], + "source": [ + "bg = c.c.acs5.get(['NAME'] + presence_of_children_columns,\n", + " geo={'for': \"block group:*\",\n", + " 'in': 'state: 02 county: 290'}, year=2013)" + ] + }, + { + "cell_type": "code", + "execution_count": 82, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
NAMEB11005_001EB11005_002EB11005_011Estatecountytractblock group
0Block Group 1, Census Tract 1, Yukon-Koyukuk C...187.058.0129.0022900001001
1Block Group 2, Census Tract 1, Yukon-Koyukuk C...336.082.0254.0022900001002
2Block Group 1, Census Tract 2, Yukon-Koyukuk C...208.057.0151.0022900002001
3Block Group 2, Census Tract 2, Yukon-Koyukuk C...341.098.0243.0022900002002
4Block Group 1, Census Tract 3, Yukon-Koyukuk C...234.0108.0126.0022900003001
5Block Group 2, Census Tract 3, Yukon-Koyukuk C...190.076.0114.0022900003002
6Block Group 3, Census Tract 3, Yukon-Koyukuk C...188.067.0121.0022900003003
7Block Group 1, Census Tract 4, Yukon-Koyukuk C...180.082.098.0022900004001
8Block Group 2, Census Tract 4, Yukon-Koyukuk C...192.069.0123.0022900004002
\n", + "
" + ], + "text/plain": [ + " NAME B11005_001E \\\n", + "0 Block Group 1, Census Tract 1, Yukon-Koyukuk C... 187.0 \n", + "1 Block Group 2, Census Tract 1, Yukon-Koyukuk C... 336.0 \n", + "2 Block Group 1, Census Tract 2, Yukon-Koyukuk C... 208.0 \n", + "3 Block Group 2, Census Tract 2, Yukon-Koyukuk C... 341.0 \n", + "4 Block Group 1, Census Tract 3, Yukon-Koyukuk C... 234.0 \n", + "5 Block Group 2, Census Tract 3, Yukon-Koyukuk C... 190.0 \n", + "6 Block Group 3, Census Tract 3, Yukon-Koyukuk C... 188.0 \n", + "7 Block Group 1, Census Tract 4, Yukon-Koyukuk C... 180.0 \n", + "8 Block Group 2, Census Tract 4, Yukon-Koyukuk C... 192.0 \n", + "\n", + " B11005_002E B11005_011E state county tract block group \n", + "0 58.0 129.0 02 290 000100 1 \n", + "1 82.0 254.0 02 290 000100 2 \n", + "2 57.0 151.0 02 290 000200 1 \n", + "3 98.0 243.0 02 290 000200 2 \n", + "4 108.0 126.0 02 290 000300 1 \n", + "5 76.0 114.0 02 290 000300 2 \n", + "6 67.0 121.0 02 290 000300 3 \n", + "7 82.0 98.0 02 290 000400 1 \n", + "8 69.0 123.0 02 290 000400 2 " + ] + }, + "execution_count": 82, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pd.DataFrame(bg)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Both tables are merged at the highest disaggregation level (block group). To do it `scale and merge` Census method scales down from tract to block group level as it is shown below:" + ] + }, + { + "cell_type": "code", + "execution_count": 102, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
NAMEB08201_001EB08201_002EB08201_003EB08201_004EB08201_005EB08201_006E
0Block Group 1, Census Tract 1, Yukon-Koyukuk C...187119401637
1Block Group 2, Census Tract 1, Yukon-Koyukuk C...3362147130513
2Block Group 1, Census Tract 2, Yukon-Koyukuk C...2085173502111
3Block Group 2, Census Tract 2, Yukon-Koyukuk C...34183120833418
4Block Group 1, Census Tract 3, Yukon-Koyukuk C...234127583584
5Block Group 2, Census Tract 3, Yukon-Koyukuk C...190103472873
6Block Group 3, Census Tract 3, Yukon-Koyukuk C...188102462873
7Block Group 1, Census Tract 4, Yukon-Koyukuk C...18091463252
8Block Group 2, Census Tract 4, Yukon-Koyukuk C...19298503553
\n", + "
" + ], + "text/plain": [ + " NAME B08201_001E \\\n", + "0 Block Group 1, Census Tract 1, Yukon-Koyukuk C... 187 \n", + "1 Block Group 2, Census Tract 1, Yukon-Koyukuk C... 336 \n", + "2 Block Group 1, Census Tract 2, Yukon-Koyukuk C... 208 \n", + "3 Block Group 2, Census Tract 2, Yukon-Koyukuk C... 341 \n", + "4 Block Group 1, Census Tract 3, Yukon-Koyukuk C... 234 \n", + "5 Block Group 2, Census Tract 3, Yukon-Koyukuk C... 190 \n", + "6 Block Group 3, Census Tract 3, Yukon-Koyukuk C... 188 \n", + "7 Block Group 1, Census Tract 4, Yukon-Koyukuk C... 180 \n", + "8 Block Group 2, Census Tract 4, Yukon-Koyukuk C... 192 \n", + "\n", + " B08201_002E B08201_003E B08201_004E B08201_005E B08201_006E \n", + "0 119 40 16 3 7 \n", + "1 214 71 30 5 13 \n", + "2 51 73 50 21 11 \n", + "3 83 120 83 34 18 \n", + "4 127 58 35 8 4 \n", + "5 103 47 28 7 3 \n", + "6 102 46 28 7 3 \n", + "7 91 46 32 5 2 \n", + "8 98 50 35 5 3 " + ] + }, + "execution_count": 102, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# tract variables\n", + "starter.h_acs[['NAME']+vehicle_columns]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def from_fips_to_name(state, county):\n", + " lookup = pd.read_csv(\n", + " 'https://s3-us-west-1.amazonaws.com/synthpop-data2/national_county.txt', dtype='str')\n", + " data = lookup[(lookup['State ANSI'] == state) & (lookup['County ANSI'] == county)]\n", + " state_name = data['State'].unique()[0]\n", + " county_name = data['County Name'].unique()[0]\n", + " return state_name, county_name" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from_fips_to_name('02', '290')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def key():\n", + " return os.environ['CENSUS']" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "starter = Starter(key(), 'AK', 'Yukon-Koyukuk Census Area', acsyear=2013)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "starter" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "geog = starter.c.try_fips_lookup('AK', 'Yukon-Koyukuk Census Area')\n", + "ind = pd.Series([geog[0]], index=[\"state\"])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "geog" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "ind" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "hh_target = starter.get_household_marginal_for_geography(ind)\n", + "p_target = starter.get_person_marginal_for_geography(ind)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "hh_target.columns" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "hh_target.columns.names" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "pd.set_option('display.max_rows', 500)\n", + "pd.set_option('display.max_columns', 500)\n", + "pd.set_option('display.width', 1000)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "hh_target.iloc[:,0:5]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "spop", + "language": "python", + "name": "spop" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.9" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} From 4aa2de458a4703a33742c3b7980417130045a0f5 Mon Sep 17 00:00:00 2001 From: PyMap Date: Wed, 22 Jul 2020 15:05:45 -0300 Subject: [PATCH 05/12] Download pums tract to puma relation --- demos/Synthesis workflow.ipynb | 940 +++++++++++++++++++++++++++++++-- 1 file changed, 897 insertions(+), 43 deletions(-) diff --git a/demos/Synthesis workflow.ipynb b/demos/Synthesis workflow.ipynb index 1c2d7b5..14fbe6e 100644 --- a/demos/Synthesis workflow.ipynb +++ b/demos/Synthesis workflow.ipynb @@ -80,9 +80,16 @@ " return hh, p" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Here we have a list of synthesized counties for hh and p from the 02 (AK) state**" + ] + }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 3, "metadata": {}, "outputs": [ { @@ -113,13 +120,12 @@ } ], "source": [ - "# Here we have a list of synthesized counties for hh and p from the 02 (AK) state\n", "ls 02/" ] }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 4, "metadata": {}, "outputs": [], "source": [ @@ -129,7 +135,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 5, "metadata": {}, "outputs": [ { @@ -300,7 +306,7 @@ "[3 rows x 32 columns]" ] }, - "execution_count": 11, + "execution_count": 5, "metadata": {}, "output_type": "execute_result" } @@ -311,7 +317,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 6, "metadata": {}, "outputs": [ { @@ -482,7 +488,7 @@ "[3 rows x 21 columns]" ] }, - "execution_count": 12, + "execution_count": 6, "metadata": {}, "output_type": "execute_result" } @@ -528,7 +534,7 @@ }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 7, "metadata": {}, "outputs": [], "source": [ @@ -544,7 +550,7 @@ }, { "cell_type": "code", - "execution_count": 26, + "execution_count": 8, "metadata": {}, "outputs": [], "source": [ @@ -554,7 +560,7 @@ }, { "cell_type": "code", - "execution_count": 28, + "execution_count": 9, "metadata": {}, "outputs": [ { @@ -579,7 +585,7 @@ }, { "cell_type": "code", - "execution_count": 31, + "execution_count": 10, "metadata": {}, "outputs": [ { @@ -588,7 +594,7 @@ "('02', '290')" ] }, - "execution_count": 31, + "execution_count": 10, "metadata": {}, "output_type": "execute_result" } @@ -623,7 +629,7 @@ }, { "cell_type": "code", - "execution_count": 34, + "execution_count": 11, "metadata": {}, "outputs": [ { @@ -748,7 +754,7 @@ "[2 rows x 127 columns]" ] }, - "execution_count": 34, + "execution_count": 11, "metadata": {}, "output_type": "execute_result" } @@ -759,7 +765,7 @@ }, { "cell_type": "code", - "execution_count": 105, + "execution_count": 12, "metadata": {}, "outputs": [], "source": [ @@ -769,16 +775,16 @@ }, { "cell_type": "code", - "execution_count": 104, + "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "" + "" ] }, - "execution_count": 104, + "execution_count": 13, "metadata": {}, "output_type": "execute_result" } @@ -789,16 +795,16 @@ }, { "cell_type": "code", - "execution_count": 49, + "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "" + "" ] }, - "execution_count": 49, + "execution_count": 14, "metadata": {}, "output_type": "execute_result" } @@ -809,7 +815,7 @@ }, { "cell_type": "code", - "execution_count": 47, + "execution_count": 15, "metadata": {}, "outputs": [ { @@ -831,21 +837,21 @@ "source": [ "##### 1. 2. Articulating `Census` and `Starter` methods\n", "\n", - "As we said, a first thing that takes place when creating `starter` is the generation of `block groups` and `tracts` tables for a [group of variables](https://github.com/UDST/synthpop/blob/0bc36f8fef036913b416e0d4eb8a3fda79fc70ad/synthpop/recipes/starter2.py#L52-L68)" + "As we said, a first thing that takes place when creating `starter` is the generation of `block groups` and `tracts` tables for a group of variables." ] }, { "cell_type": "code", - "execution_count": 106, + "execution_count": 16, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - ">" + ">" ] }, - "execution_count": 106, + "execution_count": 16, "metadata": {}, "output_type": "execute_result" } @@ -866,7 +872,7 @@ }, { "cell_type": "code", - "execution_count": 43, + "execution_count": 17, "metadata": {}, "outputs": [ { @@ -886,12 +892,12 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Now, we will define some arbitrary variables at block group and tract levels to consume `acs5` subject tables" + "Now, we will define some arbitrary household variables at block group and tract levels to consume `acs5` subject tables." ] }, { "cell_type": "code", - "execution_count": 107, + "execution_count": 18, "metadata": {}, "outputs": [], "source": [ @@ -906,7 +912,7 @@ }, { "cell_type": "code", - "execution_count": 99, + "execution_count": 19, "metadata": {}, "outputs": [], "source": [ @@ -917,7 +923,7 @@ }, { "cell_type": "code", - "execution_count": 100, + "execution_count": 20, "metadata": {}, "outputs": [ { @@ -1009,7 +1015,7 @@ "3 151.0 221.0 02 290 000400 " ] }, - "execution_count": 100, + "execution_count": 20, "metadata": {}, "output_type": "execute_result" } @@ -1020,7 +1026,7 @@ }, { "cell_type": "code", - "execution_count": 76, + "execution_count": 21, "metadata": {}, "outputs": [], "source": [ @@ -1031,7 +1037,7 @@ }, { "cell_type": "code", - "execution_count": 82, + "execution_count": 22, "metadata": {}, "outputs": [ { @@ -1193,7 +1199,7 @@ "8 69.0 123.0 02 290 000400 2 " ] }, - "execution_count": 82, + "execution_count": 22, "metadata": {}, "output_type": "execute_result" } @@ -1211,7 +1217,7 @@ }, { "cell_type": "code", - "execution_count": 102, + "execution_count": 23, "metadata": {}, "outputs": [ { @@ -1363,7 +1369,7 @@ "8 98 50 35 5 3 " ] }, - "execution_count": 102, + "execution_count": 23, "metadata": {}, "output_type": "execute_result" } @@ -1373,26 +1379,874 @@ "starter.h_acs[['NAME']+vehicle_columns]" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Finally, we build the `acs` table for block group and tracts levels - this process is repeated for persons too, here we only demo households subject tables-." + ] + }, { "cell_type": "code", - "execution_count": null, + "execution_count": 79, "metadata": {}, "outputs": [], - "source": [] + "source": [ + "# the None tract value correspond to all the tracts\n", + "h_acs_ = c.block_group_and_tract_query(block_group_columns=presence_of_children_columns,\n", + " tract_columns=vehicle_columns, \n", + " state='02', county='290',\n", + " merge_columns=['tract', 'county', 'state'],\n", + " block_group_size_attr=\"B11005_001E\",\n", + " tract_size_attr=\"B08201_001E\",\n", + " tract=None, year=2013)" + ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 80, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
NAMEB11005_001EB11005_002EB11005_011Estatecountytractblock groupB08201_001EB08201_002EB08201_003EB08201_004EB08201_005EB08201_006E
0Block Group 1, Census Tract 1, Yukon-Koyukuk C...18758129022900001001187119401637
1Block Group 2, Census Tract 1, Yukon-Koyukuk C...336822540229000010023362147130513
\n", + "
" + ], + "text/plain": [ + " NAME B11005_001E \\\n", + "0 Block Group 1, Census Tract 1, Yukon-Koyukuk C... 187 \n", + "1 Block Group 2, Census Tract 1, Yukon-Koyukuk C... 336 \n", + "\n", + " B11005_002E B11005_011E state county tract block group B08201_001E \\\n", + "0 58 129 02 290 000100 1 187 \n", + "1 82 254 02 290 000100 2 336 \n", + "\n", + " B08201_002E B08201_003E B08201_004E B08201_005E B08201_006E \n", + "0 119 40 16 3 7 \n", + "1 214 71 30 5 13 " + ] + }, + "execution_count": 80, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "h_acs.head(2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 2. `Categorize` subject tables " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " B. Categorize the Tract and Block group acs subject tables\n", + "\n", + " DIAGRAM 2 HERE" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Once we get the subject data for [households](https://github.com/UDST/synthpop/blob/0bc36f8fef036913b416e0d4eb8a3fda79fc70ad/synthpop/recipes/starter2.py#L52-L68) and [persons](https://github.com/UDST/synthpop/blob/0bc36f8fef036913b416e0d4eb8a3fda79fc70ad/synthpop/recipes/starter2.py#L131-L139) variables, the `acs` dataset is categorized by: " + ] + }, + { + "cell_type": "code", + "execution_count": 57, "metadata": {}, "outputs": [], - "source": [] + "source": [ + "from synthpop import categorizer as cat" + ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 58, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 58, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cat.categorize" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This give us back a multindexed table with new names:" + ] + }, + { + "cell_type": "code", + "execution_count": 76, "metadata": {}, "outputs": [], - "source": [] + "source": [ + "h_acs_cat = cat.categorize(h_acs, {(\"hh_children\", \"yes\"): \"B11005_002E\",\n", + " (\"hh_children\", \"no\"): \"B11005_011E\",\n", + " (\"hh_cars\", \"none\"): \"B08201_002E\",\n", + " (\"hh_cars\", \"one\"): \"B08201_003E\",\n", + " (\"hh_cars\", \"two or more\"):\n", + " \"B08201_004E + B08201_005E + B08201_006E\"},\n", + " index_cols=['state', 'county', 'tract', 'block group'])" + ] + }, + { + "cell_type": "code", + "execution_count": 81, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
cat_namehh_carshh_children
cat_valuenoneonetwo or morenoyes
statecountytractblock group
022900001001119402612958
2214714825482
000200151738215157
28312013524398
00030011275847126108
2103473811476
3102463812167
00040019146399882
298504312369
\n", + "
" + ], + "text/plain": [ + "cat_name hh_cars hh_children \n", + "cat_value none one two or more no yes\n", + "state county tract block group \n", + "02 290 000100 1 119 40 26 129 58\n", + " 2 214 71 48 254 82\n", + " 000200 1 51 73 82 151 57\n", + " 2 83 120 135 243 98\n", + " 000300 1 127 58 47 126 108\n", + " 2 103 47 38 114 76\n", + " 3 102 46 38 121 67\n", + " 000400 1 91 46 39 98 82\n", + " 2 98 50 43 123 69" + ] + }, + "execution_count": 81, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "h_acs_cat" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "... that can also be obtained by calling it from the `starter` object:" + ] + }, + { + "cell_type": "code", + "execution_count": 67, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
cat_namehh_age_of_headhh_carshh_childrenhh_income...hispanic_headseniorssf_detachedtenure_mover
cat_valuegt35-lt65gt65lt35noneonetwo or morenoyesgt100-lt150gt150...noyesnoyesnoyesown not recentown recentrent not recentrent recent
statecountytractblock group
022900001001122254011940261295860...187016225018713593112
221077492147148254823315...33152597720316222104658
000200112367185173821515782...2044138701519314744512
2229763683120135243985925...33922548744297240116921
00030011464345127584712610891...234018450123315094728
212144251034738114764116...1882143476184129132919
3112373910246381216780...188014741418413523318
0004001924939914639988237...180013149018012164211
2108463898504312369166...18841444871859786918
\n", + "

9 rows × 34 columns

\n", + "
" + ], + "text/plain": [ + "cat_name hh_age_of_head hh_cars \\\n", + "cat_value gt35-lt65 gt65 lt35 none one \n", + "state county tract block group \n", + "02 290 000100 1 122 25 40 119 40 \n", + " 2 210 77 49 214 71 \n", + " 000200 1 123 67 18 51 73 \n", + " 2 229 76 36 83 120 \n", + " 000300 1 146 43 45 127 58 \n", + " 2 121 44 25 103 47 \n", + " 3 112 37 39 102 46 \n", + " 000400 1 92 49 39 91 46 \n", + " 2 108 46 38 98 50 \n", + "\n", + "cat_name hh_children hh_income \\\n", + "cat_value two or more no yes gt100-lt150 \n", + "state county tract block group \n", + "02 290 000100 1 26 129 58 6 \n", + " 2 48 254 82 33 \n", + " 000200 1 82 151 57 8 \n", + " 2 135 243 98 59 \n", + " 000300 1 47 126 108 9 \n", + " 2 38 114 76 41 \n", + " 3 38 121 67 8 \n", + " 000400 1 39 98 82 3 \n", + " 2 43 123 69 16 \n", + "\n", + "cat_name ... hispanic_head seniors \\\n", + "cat_value gt150 ... no yes no yes \n", + "state county tract block group ... \n", + "02 290 000100 1 0 ... 187 0 162 25 \n", + " 2 15 ... 331 5 259 77 \n", + " 000200 1 2 ... 204 4 138 70 \n", + " 2 25 ... 339 2 254 87 \n", + " 000300 1 1 ... 234 0 184 50 \n", + " 2 16 ... 188 2 143 47 \n", + " 3 0 ... 188 0 147 41 \n", + " 000400 1 7 ... 180 0 131 49 \n", + " 2 6 ... 188 4 144 48 \n", + "\n", + "cat_name sf_detached tenure_mover \\\n", + "cat_value no yes own not recent own recent \n", + "state county tract block group \n", + "02 290 000100 1 0 187 135 9 \n", + " 2 20 316 222 10 \n", + " 000200 1 15 193 147 4 \n", + " 2 44 297 240 11 \n", + " 000300 1 1 233 150 9 \n", + " 2 6 184 129 13 \n", + " 3 4 184 135 2 \n", + " 000400 1 0 180 121 6 \n", + " 2 7 185 97 8 \n", + "\n", + "cat_name \n", + "cat_value rent not recent rent recent \n", + "state county tract block group \n", + "02 290 000100 1 31 12 \n", + " 2 46 58 \n", + " 000200 1 45 12 \n", + " 2 69 21 \n", + " 000300 1 47 28 \n", + " 2 29 19 \n", + " 3 33 18 \n", + " 000400 1 42 11 \n", + " 2 69 18 \n", + "\n", + "[9 rows x 34 columns]" + ] + }, + "execution_count": 67, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# here the entire table built in starter2\n", + "starter.h_acs_cat" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 3. `PUMS` relations for joint distributions" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " C. Download PUMS and match them with tracts\n", + "\n", + " DIAGRAM 3 HERE" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "As we can see in the diagram, other important methods from `Census` constructor are the:" + ] + }, + { + "cell_type": "code", + "execution_count": 70, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + ">" + ] + }, + "execution_count": 70, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "c.tract_to_puma" + ] + }, + { + "cell_type": "code", + "execution_count": 106, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "puma10 id for tract 000100 : 00400\n", + "puma00 id for tract 000100 : 00400\n", + "puma10 id for tract 000200 : 00400\n", + "puma00 id for tract 000200 : 00400\n", + "puma10 id for tract 000300 : 00400\n", + "puma00 id for tract 000300 : 00400\n", + "puma10 id for tract 000400 : 00400\n", + "puma00 id for tract 000400 : 00400\n" + ] + } + ], + "source": [ + "# which return the correspondant puma is for a given tract\n", + "for tract in ['000100','000200','000300','000400']:\n", + " print('puma10 id for tract {} : {}'.format(tract, c.tract_to_puma(state, county, tract)[0]))\n", + " print('puma00 id for tract {} : {}'.format(tract, c.tract_to_puma(state, county, tract)[1]))" + ] + }, + { + "cell_type": "code", + "execution_count": 107, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + ">" + ] + }, + "execution_count": 107, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "c._get_pums_relationship" + ] }, { "cell_type": "code", From ce27c8a45fcc94a0f0746ec2a2ebb7e341700c92 Mon Sep 17 00:00:00 2001 From: PyMap Date: Wed, 22 Jul 2020 19:36:32 -0300 Subject: [PATCH 06/12] synthesize all --- demos/Synthesis workflow.ipynb | 984 +++++++++++++++++++++++++++++++-- 1 file changed, 938 insertions(+), 46 deletions(-) diff --git a/demos/Synthesis workflow.ipynb b/demos/Synthesis workflow.ipynb index 14fbe6e..bbae67d 100644 --- a/demos/Synthesis workflow.ipynb +++ b/demos/Synthesis workflow.ipynb @@ -41,7 +41,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## 1.1. What we are postprocessing?" + "## 1. What does it mean to synthesize?" ] }, { @@ -51,35 +51,6 @@ "DEFINITION HERE: ESTO ES LO QUE VAMOS A ANALIZAR, PERO QUE SIGNIFICA? REPRESENTA ALGO EN PARTICULAR? COMO SE INTERPRETA ESTA TABLA?" ] }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [], - "source": [ - "def postprocess(state, county, year, path):\n", - " hh = pd.read_csv(path + '/hh_{}_{}_{}.csv'.\n", - " format(state, county, year), dtype={'serialno': 'str',\n", - " 'block_id': 'str',\n", - " 'state': 'str',\n", - " 'county': 'str',\n", - " 'tract': 'str',\n", - " 'block_group': 'str'})\n", - " hh.rename(columns={'Unnamed: 0': 'household_id'}, inplace=True)\n", - " hh.set_index('household_id', inplace=True)\n", - "\n", - " p = pd.read_csv(path + '/p_{}_{}_{}.csv'.\n", - " format(state, county, year), dtype={'serialno': 'str', })\n", - " p.rename(columns={'Unnamed: 0': 'person_id', 'hh_id': 'household_id'}, inplace=True)\n", - " p.set_index('person_id', inplace=True)\n", - "\n", - " # Format persons\n", - " p.rename(columns={'AGEP': 'age', 'RAC1P': 'race_id', 'NP': 'persons', 'SPORDER': 'member_id',\n", - " 'RELP': 'relate', 'SEX': 'sex', 'WKHP': 'hours', 'SCHL': 'edu', 'PERNP': 'earning'},\n", - " inplace=True)\n", - " return hh, p" - ] - }, { "cell_type": "markdown", "metadata": {}, @@ -501,7 +472,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## 1.2. What does these tables represent? " + "## 2. What does these tables represent? " ] }, { @@ -515,21 +486,21 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "DIAGRAM HERE: how Starter is instantiated" + "### Getting `marginals` and `joint distributions` for households and persons " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "### Getting `marginals` and `joint distributions` for households and persons " + "DIAGRAM HERE: how Starter is instantiated" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "### 1. The `acs5` subject table " + "### 2.1. The `acs5` subject table " ] }, { @@ -608,7 +579,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "##### 1. 1. The `Census` object and his methods " + "##### The `Census` object and his methods " ] }, { @@ -835,7 +806,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "##### 1. 2. Articulating `Census` and `Starter` methods\n", + "##### Articulating `Census` and `Starter` methods\n", "\n", "As we said, a first thing that takes place when creating `starter` is the generation of `block groups` and `tracts` tables for a group of variables." ] @@ -1510,7 +1481,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### 2. `Categorize` subject tables " + "### 2.2. `Categorize` subject tables " ] }, { @@ -2162,7 +2133,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### 3. `PUMS` relations for joint distributions" + "### 2.3. Geography relations for joint distributions" ] }, { @@ -2178,7 +2149,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "As we can see in the diagram, other important methods from `Census` constructor are the:" + "As we can see in the diagram, one important method from `Census` constructor is the:" ] }, { @@ -2201,9 +2172,16 @@ "c.tract_to_puma" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "... which returns the correspondant puma id for a given tract:" + ] + }, { "cell_type": "code", - "execution_count": 106, + "execution_count": 108, "metadata": {}, "outputs": [ { @@ -2222,32 +2200,946 @@ } ], "source": [ - "# which return the correspondant puma is for a given tract\n", "for tract in ['000100','000200','000300','000400']:\n", " print('puma10 id for tract {} : {}'.format(tract, c.tract_to_puma(state, county, tract)[0]))\n", - " print('puma00 id for tract {} : {}'.format(tract, c.tract_to_puma(state, county, tract)[1]))" + " print('puma00 id for tract {} : {}'.format(tract, c.tract_to_puma(state, county, tract)[1]))\n", + " puma10, puma00 = c.tract_to_puma(state, county, tract)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This information will be mainly used to download `pums` from `aws` or `gcs` (depending on the acs requested year)." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "##### What we call slices?: the `PUMS` geographies " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "PUMS stands for Public Use Microdata Sample. These are individual records of survey responses with identifying\n", + "information removed.These files do not include every record of every person who responded to the ACS. Only a select few that in turn, are representative of the population. \n", + "\n", + "The ACS samples 3.5 million addresses per year. The 1-year ACS PUMS file contains about 1% of all of the US households. The 5-year ACS PUMS file is the equivalent of five 1-year files, so it includes about 5% of all of the US households.\n", + "\n", + "By contrast, in aggregated tables or summary data, the individual records are categorized and weighted to create an estimate for the larger population. These estimates contains a Margin of Error (which is, to put it into simple words, the percentage of times we do not hit a target population type when we randomly select cases: e.g. 5%, etc. ).\n", + "\n", + "This means that, since `PUMS` microdata provides a sample of the ACS records it is necessary to create an estimate of how many persons/households the raw records represent. This microdata has no geographies smaller than what we call `PUMAs`.\n", + "\n", + "PUMA is an area where the population of over 100,000 in – population of over 100,000, large enough to meet the disclosure avoidance requirements. It is identified by a five-digit code that is unique within each estate, and they nest within state or state equivalence.\n", + "\n", + "PUMAs are redefined after each Decennial Census. It is important to mention that PUMAs redefined after the 2010 Census were first used in 2012 ACS PUMS files. Multi-year files contain dual PUMAs vintages, for example, the 2010 to 2014 ACS PUMS files. PUMAs are built on Census Tracks and Counties, and can be combined to create rough approximations of towns, counties or cities for analysis." + ] + }, + { + "cell_type": "code", + "execution_count": 123, + "metadata": {}, + "outputs": [], + "source": [ + "# PUMS variables\n", + "h_pums_cols = ('serialno', 'PUMA00','PUMA10', 'RT', 'NP', 'TYPE',\n", + " 'R65', 'HINCP', 'VEH', 'MV', 'TEN', 'BLD', 'R18')" + ] + }, + { + "cell_type": "code", + "execution_count": 125, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Downloading households pums from https://s3-us-west-1.amazonaws.com/synthpop-data2/\n", + "Reading PUMS00 from https://s3-us-west-1.amazonaws.com/synthpop-data2/\n" + ] + } + ], + "source": [ + "h_pums = c.download_household_pums(state, puma10, puma00, usecols=h_pums_cols)" + ] + }, + { + "cell_type": "code", + "execution_count": 126, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
serialnoRTpuma00puma10NPTYPEBLDTENVEHHINCPMVR18R65
02012000000643H-9400212.03.00.033360.01.00.00.0
22012000001889H-9400412.02.00.089420.07.00.02.0
32012000003083H-9400112.02.00.020800.07.00.00.0
42012000004753H-9400712.02.00.026300.06.01.00.0
52012000005450H-9400313.03.01.065300.01.01.00.0
..........................................
58572011001481195H400-9612.03.01.0165600.07.01.01.0
58582011001486432H400-9512.02.00.023900.05.01.00.0
58622011001495660H400-9312.02.02.029500.07.00.02.0
58652011001496296H400-9112.04.00.0900.07.00.00.0
58682011001498413H400-9412.03.01.019600.02.01.00.0
\n", + "

3625 rows × 13 columns

\n", + "
" + ], + "text/plain": [ + " serialno RT puma00 puma10 NP TYPE BLD TEN VEH HINCP MV \\\n", + "0 2012000000643 H -9 400 2 1 2.0 3.0 0.0 33360.0 1.0 \n", + "2 2012000001889 H -9 400 4 1 2.0 2.0 0.0 89420.0 7.0 \n", + "3 2012000003083 H -9 400 1 1 2.0 2.0 0.0 20800.0 7.0 \n", + "4 2012000004753 H -9 400 7 1 2.0 2.0 0.0 26300.0 6.0 \n", + "5 2012000005450 H -9 400 3 1 3.0 3.0 1.0 65300.0 1.0 \n", + "... ... .. ... ... .. ... ... ... ... ... ... \n", + "5857 2011001481195 H 400 -9 6 1 2.0 3.0 1.0 165600.0 7.0 \n", + "5858 2011001486432 H 400 -9 5 1 2.0 2.0 0.0 23900.0 5.0 \n", + "5862 2011001495660 H 400 -9 3 1 2.0 2.0 2.0 29500.0 7.0 \n", + "5865 2011001496296 H 400 -9 1 1 2.0 4.0 0.0 900.0 7.0 \n", + "5868 2011001498413 H 400 -9 4 1 2.0 3.0 1.0 19600.0 2.0 \n", + "\n", + " R18 R65 \n", + "0 0.0 0.0 \n", + "2 0.0 2.0 \n", + "3 0.0 0.0 \n", + "4 1.0 0.0 \n", + "5 1.0 0.0 \n", + "... ... ... \n", + "5857 1.0 1.0 \n", + "5858 1.0 0.0 \n", + "5862 0.0 2.0 \n", + "5865 0.0 0.0 \n", + "5868 1.0 0.0 \n", + "\n", + "[3625 rows x 13 columns]" + ] + }, + "execution_count": 126, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "h_pums" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "##### Using `PUMS` files" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Joint distribution process represent ..." ] }, { "cell_type": "code", - "execution_count": 107, + "execution_count": 128, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - ">" + "" ] }, - "execution_count": 107, + "execution_count": 128, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "c._get_pums_relationship" + "cat.joint_distribution" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "First, we build a dataframe with the target categories that we obtained querying the `acs subject table`. This, by calling the `category_combinations` method from the categorizer that will return all possible combinations: " + ] + }, + { + "cell_type": "code", + "execution_count": 134, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
cat_id
hh_carshh_children
noneno0
yes1
oneno2
yes3
two or moreno4
yes5
\n", + "
" + ], + "text/plain": [ + " cat_id\n", + "hh_cars hh_children \n", + "none no 0\n", + " yes 1\n", + "one no 2\n", + " yes 3\n", + "two or more no 4\n", + " yes 5" + ] + }, + "execution_count": 134, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cat.category_combinations(h_acs_cat.columns)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "With this, the `joint_distribution` method will return a sample and categories dataframes. This by following next steps:" + ] + }, + { + "cell_type": "code", + "execution_count": 132, + "metadata": {}, + "outputs": [], + "source": [ + "# mapping functions to return values depending on slices dataframes\n", + "def cars_cat(r):\n", + " if r.VEH == 0:\n", + " return \"none\"\n", + " elif r.VEH == 1:\n", + " return \"one\"\n", + " return \"two or more\"\n", + "\n", + "def children_cat(r):\n", + " if r.R18 == 1:\n", + " return \"yes\"\n", + " return \"no\"" + ] + }, + { + "cell_type": "code", + "execution_count": 136, + "metadata": {}, + "outputs": [], + "source": [ + "h_pums, jd_households = cat.joint_distribution(h_pums,\n", + " cat.category_combinations(h_acs_cat.columns),\n", + " {\"hh_cars\": cars_cat,\n", + " \"hh_children\": children_cat,\n", + " })" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "- **1. Categories dataframe**\n", + "\n", + "This cointains the amount of cases (or frequencies) for each category combination within the PUMA geography that corresponds to all the tracts we passed to the `tract to puma` function:" + ] + }, + { + "cell_type": "code", + "execution_count": 137, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
cat_idfrequency
hh_carshh_children
noneno0843
yes1919
oneno2573
yes3431
two or moreno4491
yes5368
\n", + "
" + ], + "text/plain": [ + " cat_id frequency\n", + "hh_cars hh_children \n", + "none no 0 843\n", + " yes 1 919\n", + "one no 2 573\n", + " yes 3 431\n", + "two or more no 4 491\n", + " yes 5 368" + ] + }, + "execution_count": 137, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "jd_households" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "- **2. Sample dataframe**\n", + "\n", + "This is the microdata puma df we downloaded for tracts 100 to 400, with a new `cat_id` combination column:" + ] + }, + { + "cell_type": "code", + "execution_count": 138, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
serialnoRTpuma00puma10NPTYPEBLDTENVEHHINCPMVR18R65hh_carshh_childrencat_id
02012000000643H-9400212.03.00.033360.01.00.00.0noneno0
22012000001889H-9400412.02.00.089420.07.00.02.0noneno0
32012000003083H-9400112.02.00.020800.07.00.00.0noneno0
152012000017291H-9400412.02.00.054800.05.00.00.0noneno0
312012000041419H-9400212.02.00.033300.07.00.01.0noneno0
...................................................
57622011001370081H400-9112.02.06.0300300.05.00.00.0two or moreno4
57712011001380825H400-9212.04.02.0173600.01.00.00.0two or moreno4
58352011001457691H400-9211.03.02.097400.03.00.00.0two or moreno4
58432011001464975H400-9412.01.02.08650.05.00.00.0two or moreno4
58622011001495660H400-9312.02.02.029500.07.00.02.0two or moreno4
\n", + "

3625 rows × 16 columns

\n", + "
" + ], + "text/plain": [ + " serialno RT puma00 puma10 NP TYPE BLD TEN VEH HINCP MV \\\n", + "0 2012000000643 H -9 400 2 1 2.0 3.0 0.0 33360.0 1.0 \n", + "2 2012000001889 H -9 400 4 1 2.0 2.0 0.0 89420.0 7.0 \n", + "3 2012000003083 H -9 400 1 1 2.0 2.0 0.0 20800.0 7.0 \n", + "15 2012000017291 H -9 400 4 1 2.0 2.0 0.0 54800.0 5.0 \n", + "31 2012000041419 H -9 400 2 1 2.0 2.0 0.0 33300.0 7.0 \n", + "... ... .. ... ... .. ... ... ... ... ... ... \n", + "5762 2011001370081 H 400 -9 1 1 2.0 2.0 6.0 300300.0 5.0 \n", + "5771 2011001380825 H 400 -9 2 1 2.0 4.0 2.0 173600.0 1.0 \n", + "5835 2011001457691 H 400 -9 2 1 1.0 3.0 2.0 97400.0 3.0 \n", + "5843 2011001464975 H 400 -9 4 1 2.0 1.0 2.0 8650.0 5.0 \n", + "5862 2011001495660 H 400 -9 3 1 2.0 2.0 2.0 29500.0 7.0 \n", + "\n", + " R18 R65 hh_cars hh_children cat_id \n", + "0 0.0 0.0 none no 0 \n", + "2 0.0 2.0 none no 0 \n", + "3 0.0 0.0 none no 0 \n", + "15 0.0 0.0 none no 0 \n", + "31 0.0 1.0 none no 0 \n", + "... ... ... ... ... ... \n", + "5762 0.0 0.0 two or more no 4 \n", + "5771 0.0 0.0 two or more no 4 \n", + "5835 0.0 0.0 two or more no 4 \n", + "5843 0.0 0.0 two or more no 4 \n", + "5862 0.0 2.0 two or more no 4 \n", + "\n", + "[3625 rows x 16 columns]" + ] + }, + "execution_count": 138, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "h_pums" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Until this point, we...**:\n", + "1. Queried the `acs5` subject table to get persons and households variables at block group and tracts levels\n", + "2. Downloaded sample files (PUMS) containing the same variables with different standard names.\n", + "3. Matched the tracts of the `county`, `state` pair with a puma id.\n", + "4. Built combination of variables at puma level - or all the tracts that are cointained inside a puma id (e.g. households with no children and no cars)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 3. nt? " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, { "cell_type": "code", "execution_count": null, From 2555324ca23039c6002255d3f89657b938a5ed35 Mon Sep 17 00:00:00 2001 From: PyMap Date: Thu, 23 Jul 2020 11:48:19 -0300 Subject: [PATCH 07/12] Synthesize states --- demos/synthesize_state_v4.py | 56 ++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 demos/synthesize_state_v4.py diff --git a/demos/synthesize_state_v4.py b/demos/synthesize_state_v4.py new file mode 100644 index 0000000..3198fe9 --- /dev/null +++ b/demos/synthesize_state_v4.py @@ -0,0 +1,56 @@ +import os +import sys +import argparse + +from synthpop.recipes.starter3 import Starter +from synthpop.synthesizer import synthesize_all, enable_logging +import pandas as pd +import numpy as np + + +def run(state='AL', county='all', year=2013): + def synthesize_county(state, county, year): + starter = Starter(os.environ["CENSUS"], state, county, acsyear=year) + synthetic_population = synthesize_all(starter) + hh = synthetic_population[0] + p = synthetic_population[1] + state_fips = hh['state'].unique()[0] + county_fips = hh['county'].unique()[0] + + # verify if there is a folder with the name of the state where we can save the synthesized files + if not(os.path.isdir(state_fips)): + os.mkdir(state_fips) + + p.to_csv('./{}/p_{}_{}_{}.csv'.format(state_fips, state_fips, county_fips, year)) + hh.to_csv('./{}/hh_{}_{}_{}.csv'.format(state_fips, state_fips, county_fips, year)) + + if year >= 2018: + url_national_data = "https://storage.googleapis.com/synthpop-public/PUMS2018/pums_2018_acs5/" + else: + url_national_data = "https://s3-us-west-1.amazonaws.com/synthpop-data2/" + national_data = pd.read_csv(url_national_data + 'national_county.txt', dtype='str') + state_data = national_data[national_data['State'] == state] + + if county != 'all': + state_data = state_data[state_data['County ANSI'].isin(county.split(','))] + + for index, row in state_data.iterrows(): + county_name = row['County Name'] + synthesize_county(state, county_name, year) + + +if __name__ == '__main__': + if len(sys.argv) > 1: + parser = argparse.ArgumentParser() + parser.add_argument("-s", "--state", type=str, help="State to synthesize") + parser.add_argument("-c", "--county", type=str, + help="County or list of counties to synthesize in ANSI") + parser.add_argument("-y", "--year", type=int, help="Year to synthesize") + + args = parser.parse_args() + state = args.state if args.state else 'AL' + county = args.county if args.county else 'all' + year = args.year if args.year else 2013 + run(state, county, year) + else: + run() From cb7b7f99db08604f73be4fd6276e658fd7c11b29 Mon Sep 17 00:00:00 2001 From: PyMap Date: Fri, 24 Jul 2020 11:11:16 -0300 Subject: [PATCH 08/12] Documentation --- demos/Synthesis workflow.ipynb | 250 ++++++++++++++++++++++++++++++--- demos/img/Starter.png | Bin 0 -> 16373 bytes demos/img/download_pums.png | Bin 0 -> 51999 bytes demos/img/pums_tracts.png | Bin 0 -> 9379 bytes demos/img/subject_table.png | Bin 0 -> 52276 bytes 5 files changed, 231 insertions(+), 19 deletions(-) create mode 100644 demos/img/Starter.png create mode 100644 demos/img/download_pums.png create mode 100644 demos/img/pums_tracts.png create mode 100644 demos/img/subject_table.png diff --git a/demos/Synthesis workflow.ipynb b/demos/Synthesis workflow.ipynb index bbae67d..90bb055 100644 --- a/demos/Synthesis workflow.ipynb +++ b/demos/Synthesis workflow.ipynb @@ -486,14 +486,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### Getting `marginals` and `joint distributions` for households and persons " + "### Creating `marginals` and `joint distributions` for households and persons " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "DIAGRAM HERE: how Starter is instantiated" + "![Starter](img/Starter.png)" ] }, { @@ -579,16 +579,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "##### The `Census` object and his methods " + "##### The `Census` object and his methods: Tract and Block group acs subject tables" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " A. Tract and Block group acs subject tables\n", - "\n", - " DIAGRAM 1 HERE" + "![acs](img/subject_table.png)" ] }, { @@ -1484,15 +1482,6 @@ "### 2.2. `Categorize` subject tables " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " B. Categorize the Tract and Block group acs subject tables\n", - "\n", - " DIAGRAM 2 HERE" - ] - }, { "cell_type": "markdown", "metadata": {}, @@ -2140,9 +2129,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - " C. Download PUMS and match them with tracts\n", - "\n", - " DIAGRAM 3 HERE" + "![pums](img/download_pums.png)" ] }, { @@ -2220,6 +2207,13 @@ "##### What we call slices?: the `PUMS` geographies " ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "![pums_rel](img/pums_tracts.png)" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -3123,7 +3117,190 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## 3. nt? " + "## 2. Using `Starter` outputs " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Sinthesize all" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "DIAGRAM HERE: how Starter is used by the synthesized all function" + ] + }, + { + "cell_type": "code", + "execution_count": 148, + "metadata": {}, + "outputs": [], + "source": [ + "import logging\n", + "from collections import namedtuple" + ] + }, + { + "cell_type": "code", + "execution_count": 149, + "metadata": {}, + "outputs": [], + "source": [ + "logger = logging.getLogger(\"synthpop\")\n", + "FitQuality = namedtuple(\n", + " 'FitQuality',\n", + " ('people_chisq', 'people_p'))\n", + "BlockGroupID = namedtuple(\n", + " 'BlockGroupID', ('state', 'county', 'tract', 'block_group'))" + ] + }, + { + "cell_type": "code", + "execution_count": 151, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "__main__.BlockGroupID" + ] + }, + "execution_count": 151, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "BlockGroupID" + ] + }, + { + "cell_type": "code", + "execution_count": 152, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "__main__.FitQuality" + ] + }, + "execution_count": 152, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "FitQuality" + ] + }, + { + "cell_type": "code", + "execution_count": 162, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "state 02\n", + "county 290\n", + "tract 000100\n", + "block group 1\n", + "dtype: object" + ] + }, + "execution_count": 162, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "list(starter.get_available_geography_ids())[0]" + ] + }, + { + "cell_type": "code", + "execution_count": 163, + "metadata": {}, + "outputs": [], + "source": [ + "indexes = starter.get_available_geography_ids()" + ] + }, + { + "cell_type": "code", + "execution_count": 164, + "metadata": {}, + "outputs": [], + "source": [ + "for geog_id in indexes:\n", + " h_marg = starter.get_household_marginal_for_geography(geog_id)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Marginals returns the total value of a given variable for the block group geography level:" + ] + }, + { + "cell_type": "code", + "execution_count": 165, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "cat_name cat_value \n", + "hh_age_of_head gt35-lt65 108\n", + " gt65 46\n", + " lt35 38\n", + "hh_cars none 98\n", + " one 50\n", + " two or more 43\n", + "hh_children no 123\n", + " yes 69\n", + "hh_income gt100-lt150 16\n", + " gt150 6\n", + " gt30-lt60 32\n", + " gt60-lt100 81\n", + " lt30 57\n", + "hh_race_of_head asian 0\n", + " black 2\n", + " other 108\n", + " white 82\n", + "hh_size four or more 36\n", + " one 61\n", + " three 44\n", + " two 51\n", + "hh_workers none 69\n", + " one 77\n", + " two or more 45\n", + "hispanic_head no 188\n", + " yes 4\n", + "seniors no 144\n", + " yes 48\n", + "sf_detached no 7\n", + " yes 185\n", + "tenure_mover own not recent 97\n", + " own recent 8\n", + " rent not recent 69\n", + " rent recent 18\n", + "Name: (02, 290, 000400, 2), dtype: int64" + ] + }, + "execution_count": 165, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "h_marg" ] }, { @@ -3154,6 +3331,41 @@ "outputs": [], "source": [] }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, { "cell_type": "code", "execution_count": null, diff --git a/demos/img/Starter.png b/demos/img/Starter.png new file mode 100644 index 0000000000000000000000000000000000000000..e5d3c163fc5eaee292d7d36a67d8be7350ee8d54 GIT binary patch literal 16373 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 literal 0 HcmV?d00001 diff --git a/demos/img/download_pums.png b/demos/img/download_pums.png new file mode 100644 index 0000000000000000000000000000000000000000..463dad08bd51134ef8680490841d88dedbc28abf GIT binary patch literal 51999 zcmeFZcTiJZA1O-U$Ig4WW|+5&|KhAWD@gDk@d%3L-@? z6r~C%)e0y`Qv^j25s`k@#@EmHn=@z5xqsccbI%N;B-z<}?X}lhzo#t{Y^-qGdBu1) zY}l~f)Wpzk!-h@T8#Zjr;NAk>DgO48d&34^S%wjTK?(KpC3|j=*TDY%O&+G^6A;9Z z*D#ca!H9u@svf>XZ#t0@q)PQ0poK^-oyfmVY- z|G-t%G__oQA5Zl5r2cb4gsK`i!9Iezy1WJk{AS@x4GsnWhiW2^BH{bNZ|J~4vZs@$ zySXp8nlVBHrK*91zG80TU}+%_!-C(*zW$!zKb$AYKLGj))`uQI0q+=Vf~%^+)!`^r zO)c=gJ<*Fu_x;ydpvH%I(t~^hsK48;uAvIP^1GFu45Ih%cgb2Fj&Ln|Lob4FP$-=e zWT`^1{Cy0A73lf<81H}pZ!)+hxLG66cmH$}IKS_oZeihU?H!zaEhsomhE|A`1|h)v z_u(i!gW--0f*ISu)zwHahLxo)3W2k6@CXc6b8x32)jgbG4w~M^W-w!QOG7hje|Z=t zj1b0jF=U#!xcmE?5Q0L2$d)9cGx)%SYHjU+v_X+rBno(`;bX?MV1+qp!o8h*C=^Yy z4}uY9?QR%k>0sk-W)4T-eLNXRJjsa|Xhg=lxTw)k3~SIs0Yq=dFr>N$(bn9;!Qa~4 zl4usFL4#S6T--4f6L%UKYYf+b!C*|9A4=Va6%>Fs3pHU{`>Tf_J}T%a?9KFIIFSjK8YCFpG?Z>jbGOyhFfuU-B9d7& zga$$rK|zHvnSS8XnkFb~8paHcfjLvcd_A;`{cP~QSPyl7tS5mHhVTv3pdcK;NWg@K z8G%b#BRzviAv7zhy#>sSVC+jXMcHG$HEnEy9q2fscbE~{Tf^VX+>gdG^Rz_Usae^> zoNejuFf(ulTX*kJA2p^q!pj?ON@93eg(1B{gW%?9TQtniItYYhh>TYvtg@2w<8LaAAH7XR?{Cw-0obp`&|{y(bCA3? zK=(7&z!_rwOp$>kQfQ!^i-x-sJjfB|;A5eMvsW`G1o{}mX+|(un6o7UZA}dJ_VXv3 znmgNt;z566U~n^ptu4+Nj6~yLik7v9hh2acKG-Qt&C{LEbV9iJVT_RkG+E2gn*_(B z(8d9p4)$s$=9YLY%E*ox;uA^^^D@Glhgwoh18@$SI71g?fMzh(#tx1P@^cIb#$ib| z!S-}4%AM(f(zKyzvdrCssTeO8Z=AQenz5%7(G(K|E^g1%v~Yk2gn8r5vF6ACa~vIR zYUYD*G7Ugz1_b*A1kf2cl(QqAWabcn^Y=k&`QidKO`O0jfG>MF`;cvnt-M)CEpni{ zqXUBk-I}#eaG-Ypjb==>HgP84!!()3G&q*-CO%%u2%n&TzqL**e<8=%)Tea8@G=E6p%l2MvOs56sw99c~ti z_BX+3g#=sBDAs637#PR+V5T|2AM5RG4vt4rsm4xTBs;L|VBp4Prc}^eD|>jLVUV${ zG1JM%M9tLJg9+X=NBTO`LueEPc-j~Tx*5(Jfu&K(LEF3l-pvWd@rg)yT$XwthB2UUXJKaELR?0;P_?lHC35?3`e>LB2!> zW4x7>ns=a)RgeXkTu2X+GmB--VjvklNK3F@!;CR>2F1{kq+w;t#Cm#b;;m7Rw(6EF zEd-q8ZD&Ub3-JzfFkz|L(i{Sv!(0$>jGv2(y1I|4x*>%|gtI7SRJtj`#f6SVgXv-H zZw&PngW#|3s9_agk2Ck7!$@i@gt`?T9vtdrZcfqice2B)2ckkewJ7#PxVN#jA;v&gM_e!(OAww^srzpIv%U; zq!t=#=HNweQG@^ZFjnrM1sLhzclF2TMSXC%YL9B*xI ztbt^jSUPBi(T&k~nh!F>&=0GHFm!NH_ea~9JE-}oyCWRHwc&vdmKY~Iiev(J@FR!1 zoA}u|)A4xYP&H_&qoacC9n8=sVF+VuYce_5!NSiE=4j?frBl2J>W*eEj(#XDvb`}bG(I`kWO%E@EsSi0gz!Q$3nmD=O%{2WnXu6{p%hZ?% z?$$@$*pFmnMECNv^K?g=+j!%G0xX#BL~|MpjwKt}XxO=9X-;Hyl#_`C7F1UZ7UN+Y z=4^-v_0)tKY3CK@OEVADGIWMY5mXpK(KB|U;=uhGdpl@Rsal{c7ze|tVcvEjbQUdy zj5Q0gW`$A=eQbP;w7k{qX_}5EaJrSHzlWhcgc(fmcyO99n6+jY!31N40vN&A%S&CI z$v}Cl+flthSK88%XiJngi{=>sK7=!g0Ra|)D2iGb+z#OwfHn6p)bw<+SA%(CwWuCy zo+L9HQx7jYOhBlHCYomBseuVY2AX62kReRE2PoVyBHbE|a7U@bJp;l_oP06rSVw4W z)S^(W?8v?Z&>RwpHl{s#|g7_oMXoZ7HKYJ;gE+9CAFWDXD8(Z09kqO`|8tdYmQOozo~ChMNSj`GH284(p-#?;DXsab zpeemi%RRF{`llX+-+%Nb;A?f);xzMZgVubWz0gL1eaNV_)t7m8CDL~{3Gi?H=Z8C? zPJ~;6(v7)#hx$FEPUJATUefM;=TRZiKS%IK-4;mePI!C9=a93h0Y*{jqUC9kKOeRd zIRv$}YS@`BW85a=9x3HTavU;J|NK1VPwO^~O-~Vs!hjFQMFjqQi$BT-I^~-%AGos_ zIHkF$RpZ}NIzy+devnB}-~p#huPBoLd&(H0wC?@cXH)p2FyOnoQ$@*o`F66w=o+P^RHzYaAKsS@`X4I zgQfpoO;!Ocm# zM>`MAwqx!;e;9Cd{?}+~HBR!xt8)LIqVCb4;gj}OT2IRTUO$`r{8}mf<=O6p52Zdf z|LJ6w#g(QQKJmG>gSGt#-xqSPJPop!7r)#ua;>EEEUnD6NPfMf@~|KFjlD4Y>D{hd z7MIgs>{`LxD*m!OKNwl${^ShxGxBy;?%&Skt^j(EAxW` ztWPsiX;3yMwRVvT14IOe0|q( zDoLX=P%%63RQPNMY5=r*dg}2KmDx*-t8^*%t9)JHRNb5`uA^*&rmQT^O%;}P(gSK& zD&B=pKXN<0WqbeIa(`6Gc->9!u3YNR$vy>xOeDpxcKU63LHKZtXnz#f-f;!%T=J(D z|F7>JG7mofb+y2y{BHH!o5KT-m!|xcBNrzWLGQiWomD}3SG7a$S6#DRbqM9*@dZ!< z#@a2bvb2Nm>Z~o#4!k)W@OAOW#3;4$qlox?#M0MKM_3<)g+j!U5zNC{mm&V_)+ExS{G3Kl@se#ZjGO;qNF9D_OH+TAC5_159L|Vs27;~w%q4leIDB>CliNU5Fh#c0 zxK=IEsy1S!pHFAFgg>&uT5U8*905!L5fse8-`0 zC$YPZJ=v`pc%|g-kw;a@36>E=%BLJA@*-PzzW?Pfx8T=~Q?Kl;5kFl6W=5VUykhIg z+z9&AnZ-z`!${3kXQ&*m@-M1vj&6Bz!`$-Mt3v0Ogy*P{O+`*lB(@O*Y~z&;8(PoGN{AHugXME7>-)#HcPD1SL}kbA4Qq|wcIqpb*ocz$UQO@e zhM1{)58s#0Jm+VE0jM!^?x{llIn%dQ8GjatliWM4q~Q6DV>y<$9}aui9}4|;Oh}vT z(~>F~5HRR_@krPmo^6F%PkAMfH3XAlO~!b4J+d_+^XPbX#Nvd)UDe7Df;us@Qh~91 zwMWN~xh;HsI5>G}^Hz~do*%LT9-F$1^9wcY>AUi>_{=finXMAau6wxdlTx&r3q|13 z$L?Z2-LGAR(JH(;#DuoO4L1k9i(Ff=q2zA zN?TQ}o^`YS`aJWEag=jEH*a{L=U@@cw!#hqKj znXey(GeNHylwgjjTq!}fJgaL)I_EdCoQ|+=RF9_U?3q#haryQ_3||(p$tZQN?&Quw zG{H77^*gv>t>vWVvA0Wl&WTouA}Z~hJIwc;)Y*Gg2Dy9V$^e+!3JC9#FVMKL8R@v^E3=oNKb?a8K7 zr}s4@_-2-RNvW5MXQKJ=dq&7U1lFkA7MQ;<@diuGmES?zTSfysxb{n^{dV@_t8>_)1i{jX32qsxy2d`7t|{@p_Vit3e|u}1k;N8M&fY_^j8<~7B%kBtBzW-~ zs?{w5nNeBfeQ+;(6ccyhRAt&m>Z{wfKf_%Idp}rb!k><~oXS*W6mJknvVMbbKW=tW zm6A~e<_%S-r#f_H=xXfH^@E?ke~VPsjaNMQMQr3eK`b4X=F^ZDtdc>piHzs39cnmZ zNZ#(AIwPAMXf2ztfropn{W2+G&#tW_F%cz5c|q;=RQN}=p}k583ijC4@Jhrua+RatPSPe?^y~QhY|9M8bKU!SK3CoRy9j$2 zj0Yxw>ecOfwwOPSH&a`sDM#+5iL3?LyvF!AH}zOaGNX|o?Jizq%~l`g!_^WIu-j+f zY9E1M-R7pa=cmSu2DwcSB7$f|G2s%b0Zp8?P3OyHkKDbjlC*k8hGB9e*Rb_1;{!Pw9DZOonQ9 ztjeE7D6I?v#38VSd0Vl8GG0d%Rjf`mScmpD5&DA?G61N8b(@=n| zujkc?tobtW2CO%Q&Og^=QxCybKK#2;(42^R01*95zJxa8_6d|nYuba2PA&hzsK0-i zP?XA-%|EwVZQ=AE`mz4iZ2;7t?SA@A{@U_rZrJDj%(uR`Sb0IosmiM(^TzQAT4yp- zJu*_%H8AQOU`_+_7hTi8vl*xUj>~9>XUkwd)vm1u0Z{dz!=L<)O}qAv-lk&jGHP*+nk{dNcCJFNZb5uiAAb9%y0N^X$ ze8WM{jYKQA9<1qJWQ|?+?!Vx4WCCD@9n4p@xV{;;Dn{S+TEH80rgVkE2P8sz>vO`V zDpM@=NA3dZJN3EXzEx-~pj8y=`x+J%Vs6#bkAndJ$q64xP;|XvcEPm(e=kXKG@mut z1HgR_t$BA*@Rv7J$*A{%1y1)vAZ9@lS_Mo>dl!TVL-^didW(ru)3s|MOOs`(;wWnN z?3n#E)1TEGU;8?ZVlefug|Z=tw{RsntuzZ$w2#MjZLhUEb)d`@vSQm+M3EZOf6A|sUrTC zi+%gSdZ_mu(0bU$`kSbn#Zv>gQK?iWn0wDp;P^o_b|j zs$-%$4sbbCtz=%JG&3!I6jYQ8TJetz_ls#Jfz1Y;P%qy8k8QIRA zekBClbrnRMP5_=*bbR4^Gyn6sZtRZDfZ@DJ5FYxz+;F=)@!L@S)WgAuAl>kv z@FPGu$V|{L+{T@9WmUl{n-I7s1F@@iVJu65gFgu3_Tgas3B4C%Q%e@&c>G_KdYTIz zSy`Ij@j*R=f}{Fh)szIH-+Tq5ov9D_fc9F_tA~H5uACgG!e_c)6iEKCAaS!w$6)-8Um1DEXi1><-uP*O=*1%*m64Z{r@hLaFv&gdX zYSgbY-V)!sOYY!mSfopOC#t^m+|Q$QpH|k6=PI<;U-@w^IOw&bQze+Nl}l6AU5{J7 z`U07xC}L$1c`+yC?b8Uoh~>~M6i3>9_C40fri~|W*I%vsrOVW>J(-_+Wp%lQXf)zN z=<(rx=oZrVgdj(szUx|9njA-aSu968B2$zQ%{M#4PT8g2pzKXpSa$#TR51_U_B>lF zs6S3JVjQR?-tN25yY4S^c_#ChwRepQH!1p1S66GksCyTl0uSt{;c5eX+n-SwbzBze z65&(;RJRO87?DmVZr$B*a{GQ&OY+aY{!(Yp*)IVlE1NAferhW3W4Dytxv^bRuOE_s zATGI8E~cA!+R|>57=E|1IU55IDJ1n!T73zsz2w2LFZX`xs`|PLU4%!>gC#?Ro2$Pk z5S9#bZc;uK{zI0unHzujv_hmC!(>mNueb}!7 z%r;WooqzhtXP~mFiNaiY`wnRYM0a+e1}8I=odr=M(X++79syDwlJu!6_JYD~{o3wf z?c+dt>bk{)ct1HK9I^r^$fjs@3jr3PN(@Q9 z^q_lKPqyMrM!a=*e_+9n>Z0eV(N<;;lllH5)S7GpHw!mVF}q0E8eco4B!1MjXBorQ z#)03CEG9RY;_G6ota7wP4E4i*l7+CGD?!_MHZQMiPTv2s>crB|a)StWMqstytJ`P8 zztwXMJjY4q*o<$J(0+9Sy!3i%kX_>3!ht@fH-iKV^CQX_C{_M5QjlV@*e)*cB$WF& zu61VC_L^}eRPySAx2qeS+Qc4qk412c!V85_1B`R(GWBSiNOnA{g(z@Jg{H-RPP`$* z!!bo_QXR&BO0d!2^(Mw&C@(rDrgyht+Y`~Fds>BUPqyuCDXnOaQdbnzCfqF+R6in? zAVkm++*#Krq#_p_Z+T@%zbEM6k7z!B5oqMIQHw1NOi^ZJ;nF8#F!oEu-+N>e$R2Oi^2rbQ(s(c>?iv)1e5w1$aD zEMB$ZGvzE6tK0BU6BYwx+@}$r$QbqAMm5SI6uxApH%QI6y-vywE zMuiS(Msd9of_SxyKpyKaq;iWz%a@qJLy7s)>L+U#x{R*>Qqg7`Z<(n#6Ahr2km@sI zKc;waqG=fE)xO(Ge|sq29H4BJaS4wUgC9;%hxN5~#+vU!FpA%Ml%6%)En2bCgcA4^Glc&a6;B7m2QaUo@hWZ!*DGf3q{Jn$B0PJ>^RDe}p#pJ4 z{M8r5Q^PK}!t*`FcUg0ZFoaeAPktAVf<}33%fFc43~~lc&vp$3o6b!RZdf{)?C*H> zmw1Z&mA$Atp~;gz?4S$hyX)_sE)bqNZY#KVx9gG7RDa0?Q5fY>LXM&l+0=(NapR(w zVAQ`2i!1=5o?HHlra^oqEePUcR8xfX-=0{fL_9h11Dmebl zzi&th&_Y9UAN2A6y`lg2pOCG9_RE`=K?uKBffo)q^2T%nN%XTSdx(QMRr#q36x&K5 zxVP&re{0PD@imwZ;lxz^Rd(x&$oz8Xx!rol*#O2&_q#C%gf)BANzH7Hu0v%uB2V`^ z`QUsthYIdLrYkuWF*-64iSL#MBiFw2=`ROzjVf4XUMF&Xw);CWkU(Y;D$$WSfVt&X z9WwR3?cgBUei5Mks(Tf04|w_kaUu}6mvucM2QZ#0;5W2f*l(}!F+woM#x>urf0oqJ zJXQ-}mBQl+fC|~zHSkqeP#Z1fV`JHme!guZp8W;9If<-Sz>KSgD_y6UI$s~yM;XPf?bv&$_tE0#0xD=) zk#(Nl)YU{)I^-Y$Xv`?{?h1)7xM`V{dE+L)^ifJGJsYAIH1l|en0|};#m}z` zsuK@B)(q4G-5Y$c=G!S9z*Po5JUwUm?bw{lqpn$_^JF`vYa7DZ09lIyV5;|`ji(LEOXza~nzGt-* zniKkcR;NqMR0zd&_m0-SS2U>4ARZ7?g9QkFyu+6#B+I*p9~MERr+*{Yo*~Vj zXK{OJz@}2+*KQX@6|7335-a{>0aljYg|0Lx;KwsL6Mt^5lI*{+q9V$rLv)d@Yamzel)gi!vRo?=h<@G1o#R+SG5lK*~1kGLHHs*2+ zug>g=&pr18Zpo! z78rENB6xvlZkaes)vTbx%?U0t`B;6xe)4kO-?S7jvpROCj+YJ|VrHA`EvuaNky0?D zxQ;XnX|rpj(|gCmlOsy}hMvX7MAO14aS|bcl2ai%^0EgBK1S91EnZjL1$ZzZ- zPCNUZ3Y7}f>>NGm=>xn(5%beel=ez;D*Jy)7T?NO6cgXryCh{Yu9kac35!vj(6^P? z_Xk?oSOCQFgmc%=3Bpd;b6)T`(joCA1EHMT4cg-5I{5em3HyCGQ6OPA!SAxGxMb2}bW9tont}&vfYlVkD%dGco=iqg^w^uiekZ}-LcIe#* zzw?w2TZOdcY`>MBdA>tkli&#iFHId`QCOi@d>oWk;N;-hwCvo|`XlyA{mM2`+ zaH2URmEGjHt`Ma$ll;@1T!u0YR{`hoz`1A589vM02;~C_ z{a;_Gdq*o4MGy+jN}p8gTWJn+Chlk`xBM4Vcmc_?IgB9oG=x^bV0S)lMiawCS$MD3 zEsp%SI1wb2oTn+OER(<+dy`Zn2RE=d?~%xi4Bd=1l}z!^{g+^H{T#r|+7n|wg8<%? zg`N{Vdc360&p<)-pq^~VTXy7jG59{!WQS2U#VY#d*(hIePut`q-F9-P+CFaN(j|Np1ikX5J9E)B0Fo!NGctvTMMEekqf zKt~(cEb2PcsXOoLROG5P4_x$0Amp*T{UdMHBoQgjl~Zf zcZOvH>1p7?!K06dj=~yqHECDFhoZRpU)`~nz^@B?p?5$s3B>=>57$OK3VvBk#P-}j zs^0@*Ehr$uR$J3hklc>aDng&$q7dJyw?qaxsp-mdR@zTh+^Swt07%Q)7MGU?wBn+} z52;gN{Rg-Zm?~w?ERYk>o(Czq>bs5wRbYv%1k0-8uzgV8qfr=aazn9bLy#w;(L#k%vLRKAe6`InasoV+-~q|H?I2t!$DW`rmcH)!{U`W0SolDGxg2gnt3k zWdI}+2LR3d0vH5o1~w!1lp|u{qbRV>`Imz4A9-Zaehl3QhJQbBGrZK1a(fM0$$*SN zq!z`57b4jAfu@PTT#>S{(w%dd2mI&qyFLJvd=hw;L6ArK1_FOW-aMnXw|4QfQriYm zd|RBiDWULH>bm}8KwVdUs>T|}48iUYx>3fvcnOn`P|Z zmU^}o)&joRn*&mxS#H{AyDPsxQ?e|UE(PQn*7Go6(8ftdGFLvI!`}OMmDa+oBkar_ zSwfH!#t@K5@qUEvPustp7Sz1k`;uo&Md*yX`Jt157G-N?NJ$+Q!%P7ElNSE9-05v> zHhA(6>h1r@9cZDUleJyik#&x|^N&K&E4M-S{k=xN()-o%1mS*wGw` zd~1@2LW`Xx@r4B9jD)Bg!FhV64y5c%aOhr5ckW-1+ zh%xg(-q^&&_ds1*59Fd8TE9PG7gc>e(6;&{+r-{tlJ||==cj2gN#~#LSps#8T^aNV zWZ%#D+1)OUTw8_K-z@GdLjLK^GVgzxa-{jmE?vH;m8>PiJl#6u9$@#?x}`-iZAX{j zy+{9usB%!`resMLEWPsk836k`=7PZYVHU5UyDxhDSPWDg#Nj?^D=A_s9`74I^T&4Q z=Pk~CIXuX{%}$Wy3v{2v1d!|_c=Gz^cGq7h0;Ve-er_o?1XzwPTMm{c0V67C3Q+Be zy!$`}DKvZ)v0FFn!IQW&g|ugyQ+HWZEZjrovd_*bIEUSlya*=3t2^Vr zEx4%T>#cm<3H3LxM1R}u!y}u&lOEM)p6u2djuz?%)yCdt>t?4?(1`;tMB=0wP|i`w zz|{Zc&E&>Kti;6xAw?ILQAn}^e$M45o?x`?sL{~PKiwuSGXbF9e$9-C67Jz=#xk7B zibt-kwt@V*#|YQO3Sf!15nt!$c|==v{}Ni^VZ9M=u7C8k@)pt3-uz$`m_yeuUJ3iX z)u1(Gy=c^fq9MhIx0e1XKakwCVKw&3&|=g5ZYWiO(-n&5Gm;a4v*}MN)S^3oOuW3; zEw^1%gV!n-l$XsH8{WRC4D#*)Zf`-`Iv;&S%+J_*4#&Q2k*lGjPv%l*pcKN`mfIOx9H7oU z-P5sLlkUC0v#U=rw|r!f;RLjKkj6^r)&AHx1|A4G_hp}n6u%Oq_Z4YQ3LghjzmkzP zhpQNODBpnPZN&Uq-ji7%RzKfV4yiOLyg%955C<&++9OX~_CDjd2>$(q^H62zF$^Tm z9V>)4;Q>Fe{KGqiytvZ=WYShvW!FAGNcCOj^WUki{cq-J_?f&4sYB`T8W2+lDeT~} zEjWvGMaD>SEr|T{umVr?ufvlut z#Kz3k&1l2oJBn$mKVDj++M0p<;w#!*z8$3my8v3;kt~LI_7!M13MY%rTq9TJM9xdT z66BHK|!uvgPyD>xz*Sro0C9d$FKJ7Th9!)8; zrzOa)#mFxSV^_djJm}2O3!BX_q}-N7nX57mGbyUVYmrK@#s`= zhX!-qub|A;r>}0Vk4fy^*O-@bpb!ez8Ifd=$}NTl4BwNv*ZfKAWCf08i8I zqwB3*U%&?Jc1MZQstzE4B|=nb*RrZJ=+?!|aprri$`A|Nv2(eO9pw8)m2oe08=$=da}zIH zK1VHl3AM~U)OSY5KJ79ad&JCkuavENe7s0mhgquzW9RXOAOqQh+^(V$`- zJv^J(CW z#!e+3>((_~JdvJI^N(KcMa)NvZN6xVO}!93ww9}D!pRwPCZP-33NiqOu>X_v+Fv7E z+xQcf4sv8@yF(f`4<&l*ZiR>M!~At>!9>b%{tndi{ruY8Vx^8&mtjwe%)QL*1_5My z3#G}UP^Sj3p4OQKgJpW3SAPi!SGG&Obo|&yNV4{(r^s((CGkmfn&N=>o6A<_1 z_lu_8Gxaf>I%wh~67>zx)94o1`P>IuJe#j+Kc#aJfHK?a~?V-dfGxlry+@ux`q+CQ?!Jrfie5o;?0LeJfr1>FwhWcBMe=!-V~^ueBk0TKzy)%f9qSO{EmoUC z&jHW#TkSfAQT*_X%cH5-Pt)0?Zo0EM_AYS$oi!8F#Y=PL-H*C*0HHGG!v51R#GAvp`r?$zNc0c=YV+DlXLE=GQftwBBMe#WjhR{@XdaicvEj>5!=9et%& z{W0S(Z%X~u?;yA(lBB+OtMz!z^7posU6O?+aAikeIvw#**KXf2jATx^Dz&!jH@Sd3 zf!n(ZO2=0#pzTQMLXt*fdFvy;AUh9+wmObSj_%#)8H1{3Kd|}W@O6!6+}V!K#1<6; zm*7`c;{hyG9-q8^4O*Aq&01TTAGoAWn%v|1V&D7Y4LpjMggH_7K}5c>P^M|{nA`9o z1lpiYK&X<*W*0{BPJwe8^bf74j9NBtC!S3*ioI`lhbK1pRS!4E6=VU`%U}kyb!Q&&wk|XxZri-N z%)KlbMPMTRr02fA>skJAC$;G?p?ppLinr<00iMbRy|dl*MqfL1rWxiL%IfBPky-2< z$NNVH+#TXa(GP}-GR|~M-_w}L2RXSRy~T0aAm=BKI*!&V>d8qz>8ig zE1EgP0$9-%ApLuihI_isg{laBF-KMb|FQ!ZvaKWMT9LODfSaxj2+FI=H|CNo4jH`E z-WaUPv0J9@u=VlzlF!{HvTa*<+N?}LAnmPl#%*A%%IR)Hdawt+c^$f4fqRj&G8hGl znwfIVXi&@vnf%j3tvwH(UUnTEZj3t|qEkrnxMp!)Ri{RWpqpSYwT^^byuO3taK~R$ zCT(Zbt=zC@GsD(>5wGvQH-93D1bt%?ao9Z8v`GIk)~4{D!Z)ms{+ZNS{Ew z{LNaVFisQO+#sIXbIO%cfx`590$MWLB zefjCWVHtAR{kkn5c$dhc+D((cNa4!`miPAL${P8~mp{H@rU0P!N{rkyZqROc?ayIYI8<-Xy z?Ai$H6KIRhqK-BvmmdQC%>ya2lRx)8B2mMeeJ4LI%mN zx$4tR#)sZEi<86xoE}ZDVB*4d6OQw1#Y;tBuDwkpV&V+Qkp}Q0){hIfk?}pZfUGc} zx1V`_`{Z=>v|gD{Q&l9)S$Q*%z{*^Zg4$UJBX_=Gf-L6P8FP-!c6J4T$2S3k6T}B( zd3SWjOM__3m0nJM7&kx6aOP%MW9;?}5m6>eS^IrgC4Yd)oxUgoQwJfr-TBzaANA#| z@XoQO0^N~35RCd1FPlQ>2-ZZXdaN?$ zW~#%_pL;fMY~8wN3BUKcR!Ug;@sFDQ_X#Ce9d#6)(KRA+jD6=#wrCzGpCun7y?x;O@_HJW zpF3|p*t65~C;RSjMQk0qU8-T>)9Wh@pH1Av$|q$`ZdFYdm4)W#8ni9OoryiKFC`mm z)+i8FC~Z^bWr?DV7&?LF{d!AMaKd)QCnAY201o6W59~~k3FmyQ7+B0NL*3VE+Gr`X z(NJ&)XO&Bc;FaRfz(b{WiGe&-)Y|X(i1ZoBGy&}OVGxfJfV6bSfIPhuVP>Po2`@nB1=)elyU&@4@E?O@KPB$4x{X}dqivqd?EI4jkQUCzo{;*y z_)GlG9UymIet`%M)a1PSZI9xL7Dt?WS#Dju5$uSpaUA3G^-O$Q1P8kW#955hb^2=0 zXQH`5@xq+k*Tf|z0d0#e!eFgnCi78JU1A!5$BBp3US`?#`_D}pIjdJ5Q`G% zMz6l6O|K(1uJa!NVuL2*?<5v%WshQk)JW{EJtGuQjSuzYW8(@vZlU9_8_d50E1gPn z^3FREqM377RG<~J&f_0gL>d^A7k>xNJanThbX%V89Ov2Nrz#y7=nT9nZvMPrXp8n8 z`&-&mI}ie`xb^SNS)2ghd;9x)AGSp?^jpBvKg$u-_%6)#)or003LGVzCKz=flolj^ zc;e%BeC7%M)7E(;I79II8HO3qm8eAaRvS`TpPRi2n_+D3T`*!aQ#EJOMGkUS$D_t4|1AS!UkAa3ccWaKhY(S5=hY$Yggt^BSa zaf3dspwA((pFtbw8H-6O7%R+}R)jgor8d zn9g6{&JQSF+uj1<52D)8 zwgqUT2hS}DX8-fj1Y3P$iaiG~8yVL#jsTTs2~_ZY@b?&MoCj`rOu5m7qsY==^4DK@ zfmJw_cvTwGj171>1$A2#EiN77hwJ5#1KB)O#o8Gt2_24{|<;|pa^syf;9g@z*epSV%nl?{0SuKk!{^z zdFlt7N_<-&C^-NEH!0_z`OWYQ>Fqk$nE6wxibPKUT%6O%e#d2Q)ibf{fBIuT|F_&x z0)-#dG&E!uQ>Qg{iDWmvAGO2MX#7}CeR79?QwD#}4`>5TH`qlIr0ly%MCSeqFv<9c zrUSdmUvc~FNEbUOAwhxWva6)7hYWk4So*q2ZE*5aD4>THLqlTGb@|kUw`+p&!rJi{ z?>}CACb*N_TU_tXfW&Qe6mAbK8fXZE?TZF))FK}Gy*@AxwCK$4%CSs;*ROBOw-)NT zyB^|rdwOSTUS|p<-uv8(OE&(m+ZfV%43-V&lgsN0I*{LYc6P2{1ylja&*Ir-Xa&Ru zi=ALYPsvz%2rwrIG91yJ^<0vZK#DXi>-<&?{bdZ!6n*1cAaXaAZmvoLF!=84ShR=U zuc6Z!mkd-89GBmpo&+0;Dsm$dUHxROj>F&RPf0{GcBxFRHte#eElEk6t*x#M0EKnJ z?7{)zht<9>Z&m{RY-g1fNJsXoD~3Ogwko|23w6CI3EQ2Wsk;7`QdsDdpMC+Qa}*Mz zm!Qp7l~6`}^()x^#j3wjY+B*-yaCGCQ(s&+9m@=PBJ9M55*vR4-Vd*H#EZCJep^BD z-`y~@2r1F!oQhpvt@gKon9G{Hm zSKbu4=`g`xdJuJar_?vvkd3|i80^;kAI!aVR8?ym_N#QW7M%i%R+Mg#T9hEA!a_kQ zgI-93bS=6R=~htz36)l91f)bk1*8NdMN|+_&pmPP_kF)JzVrVXgW+)N7UrDmna^{_ zb^UH_rKlB$UB2|TA+NH(T_^^U{lQIW zm$sXHM4zW3QZzPTd-c8G`s5ZUAzvGgnhlc255Qiw2Da_xog6;mkHqvU(@&vL6KEPr zxRYv~JO}oW<9okB*eA0+l&>0?{UrIh^fH;PzP8HVaS6x?AI~#e#psMsiN#*-y(wvX z`XkuJBp=gy%i7Zqa*9cdT%L>PCoDRIYo@aL zqeY6+i^z44-qzpN61r8rg!|j>9Hk^t?WRoIE>{t6`DPY&D~47>NNxX2f$7WK)Oa^d zK`p7D5AS-?hkrlxaI(y_#0p9{r&V|Zkc8la#8}0JF_LZ&DcV%V;5HTp@|+i&LA2(E zC=oq0wU)lfM_gEfbNr%T4E9RfchS^-@mqJD{fShtq(X!RJU3Xp&r*=f z^xum}rN<%$G#%Ox6}@SL3pC32G`9&x3=M zc~+=7J!W616h-K17@`NY=dxYK7Y7SA;Ecc8MrrUGy4xE_2f`pBjG6QyMUKw~mlFz9 zW{6#q@kGb+W?dqM!D#(hgxP(5u5dA>{yp$>%5O`@p)TQDNw4S^n_9$;uGD+L8I^w} zOLH8>vnaa|i&tDKj7ZQJ@(4bx<#hexdp}8he_}97_V*mh7^pbDaJnG|J+Dm96oR8Dna>vaJ9ou4{-xZT`*{ObP^Rm$YBfkPX31-TN zT1b(Dtz4|$7K%!~8DGNBeyM+D`iOF-bqvvSlxyNNnmzRbOf!dO#*aN}9+?CgvHAA> zstz_Qagkd};#lZ2L>>u;pJFLAyOSUNB8*&3tDnyc6(O+mV)snL^~<#`twXhPq}+?F z5>@x`;^rsTS-YY?If0unhk`r*QhBVruUG)Cvw0JO2&V5i%DmzAZry-nYpnHW|aWpBoD=k==sPxW+`Y=$B1O=|ETt{SaU6h29+p?;kP z%M=npK@Lq1Z(MMG$ZvmT@_0t}UQj5O>IyrOt=r>n6I}I2QA!&3M?Gfd0y@V1h~k)5 za5}ywzh+u7XAR5+a7-)T8|Aq+qPGt%#OIigdF?1JwmvLH z*bAw~_(`vm4j2XNzhTn#Bz4^2<{g9EECN!~759Y$nt4Cx65pe|r4UxNKIzA3yJe`Z zESmz-yUT8d_23|~eaBP_WWWjdPP6eV}L9?3`k4*W5#vjPw9 zXcxep7WmCl8f1rFrrwt7z?=vL_ZJDKTK`*n^9(&TmUGkiMyEIJiouXaJxN=Vx4m0} z?TgUER~*}ql4;q+?srQrB92t6H>k(BR6MVsFt3TG-__`qHqPK#6~DRUPLi20?NFv}rcgn- zXj%nM`!uSdo(Ekz1<#2&I2|G>*3Un7h)hyj;TY=SD13yz8XxYt8$ zgvY%5La5_A5{D^i7)6qh?Efj|%hV8lEBvefUW} zOk|?zXA4nwP$nD(ZKdpHmjDMvVm67`v(zckg!i7gp_c|nY9R??#RZ6b)$I}_iubVP z92H;Ot~0YC2Jy5KPRqUDm|6t#D7OxTh|}0 zQDjzL>0oqhS!HKWxN;-zSfxm&)VsxInJGc^F)W#KT)bV>)aBdOn$}d5c_tpwuPrN8 z9NLPCE*^+E_b43tJaY{VMqd@Okaco8mcAE^Iw9)w=4-P0(}|{7^94AZ>Xf8i^1&C! zs>H-~XXk{Z3{Dz)W17b@**nLX#Hvf*2t~;`KFTt_eZm?MP*>oc9&AlF1DB}D{n^j1 zFS2eE<0EI=4{vr$hqCgFz7%yTM~OB>m|YV-UkllIHzK`HJff;Js;2bM1)hKlEaCT7g>etD3eT?crVsm*4&I zPdDCYd$so)vec^6z7Q|G>a7a+?)30U#JLDVYs3lE1ZuoBuJw-)qGvsc*p-5kq$hM> z>RiV`De3qJwU$5h6N>rVl{w$^ZA~~VpI6z)xlgI2Sn9tbwry)B6qRgl_uvWwmhazO z)R-&;K}q(D2x^)Z&AV1HnENW!P}{jpR75-muAu=Wymp&@5f;|W{<4B(SQj(8XLT5je?yUU~Bw=vH`?4s6!}--9`l78YWnPtD^tf>*eHJR_PUT-E zWST$n`XeUY}?Q;*x$g10&9xn=RU`JJH$sL zCI;1UC-?Hp!(6^W9=?G$PA}t^a zB<+R@ayvIvOoiGQ!1$f13oTIBW}M2k`dmqKtiI`jh84ZIG(O_OQn{a;xa|T|RxD8N9aQV?Tn1Vy7&kn1DW4qLkb=9?wBo#McRWkJ;%^-c z6U0KnZB7hIwy8AL1rj_`d~^oZf6pxeeO`b5C9v6k!E_NzpMs9mCrh@{Dh5%2?e*93N8ecyowf2T`UbE!*_~oN$p&PPiNok zH%V90(G(Un%u*HUk1@QWTZt6oVQ*Fc=eDXgdaV{17AD3!>^e8?TB@Gfh}yIpjZhO! z9WyUql5-iiIdHJEa1|sBwbI7Z%49YAO!;5^z{_6-;o+{(9i>Yi!=-$=3Jgtg0NRPS+CUI& z6rk#Oa$4Gh54tT<8tq+d+kz9r|F*;E6^^jN(GK(%rX zJ_eS&Qi;ny3SoI=aW_={4Ga#2S@|a|_Nuf!JLY+?ws@yUu!%xxWHwPRI5h6c&bpL+ z3U6YU6meK@dqO*$2CeL8NbMlULGIOPPU~?xi$_T7VHT@*F;p;Y^&%u5b<^7*Ykj-C z(hNr?3%{lneb(5uZxQ1f6rEJ?7Ll`m>XGw(eOf;2%?gwoWsJ&A4{lGxg`3;Xv7RMs zBixUl<`+vIB2eayC3#6+HWn2s`1z2zyqH$UstdS~7P_K43DITzPh%n}|35d2V}qMz zulP+8 z>@BAmL*ras&948O{qnxVI*<65k0F~@S-N*a%?Oz|vENB3l~T&?sNvd)4o>oQcig+S z{`xL&$mX6bi&_ag@ra4iSpQ>8oex{#5Dg-yKjLz7ha`njUOnLAga!W5X3hDZ&%6KR zC(?K7zuPw(PvyNlVs(Z!s_t1m(~MhW6OE($I{`kcagn)Vrn9T5nDi2z#G`ud@hddz zGW8m!?t*1M!R~)@CSPmWdR7(hNcDiOps(Py?ZEL5B$`7(X~(vDM%#bFGV~TO;|-2m zb=_CBeKj)`H`Y@X(}bzk+y4~>ZtjD~3SJ^jj(uG z%DC*#8xS5z=kBuk3Un?E>!KtU{C4BhCiSSWjs?Q0FHnuCO+<(FngeS6Y070HMH1XA=92t~EC%!42CBf)HPpLRQ?IH7Re!>MU1|*an zqMVNyDhkE0r(dhTX-biXyN%UcgtWWP&|*rFa0jH2mQO37d;KCoa_6@;EmE+ zt?{ova@*2xT&}RYP&v``dA{sfZ46Rc9Xs`Z)FclC9PxB+*Del8a0W|V{3|}$+?$?D zi{?=~aSZC^j}PHTi2s06Zym&qvMW?$SG9~-ghoclm;>jz?5^u1aamTKs(;a+rz|fT zKL9l>r*+TYZ5a-0rv$tpYPw9y;L#Ur$KN7uM-$JvwSzdb!G9q3nwfT(cmwBKY}Mdf zQZK}DW&xxe4*C8?7Nc5sO|VJ_{vOO}WYPICh~N?zVy)oLTXl zCmgF=yTE@+P3NJ4&~ATjp9v(@@E%ZHBw^9-a9x9+=K~gunw6RcT?OC=I?WU=SbE`a zx5sTk_3uLwMda^ad%{dg(pUN=QX}?`RO^^JcPOT2XYNXre*G^02-6~_WO_k1QP>6Q z$F_{LMbE8%hSD64YCOOslnbQ5OAjTc(^4Am|4K^CiOWewk6FS2eeR*|Ur9-kI^Th$ z#KzmWXEZX9^9eRQP5|V=1Cg|%cfd>P7K=tq5uhr({pB}+UNVwOl9YPQ_$f=Xjs4F3 zA9e13o+9%nkDr*z==sB-my*@Q`BbIYL}?tdaV+|JqlP8#UG3GT^~t6j!DuW=eaCkQ zL@KpsS_|!xak#486x8AB_Dv{NUog{*87~G8{rlw>o3%pFh`4!fW*789L&IsV-RUcs zE6+cz6L|tP=67j|DM3l+1qsR{e=w`z3oLgwoy9OFRzw%}@AYiYO3{4ZN1i2foYFz2 zCx-d^EXh~8K{|9x`ys=W$(#qDs@&)M`X$_tSPc9uj4ST}$+eS~U8-ZPcJSoFNxgG{ z9c+@OjKW5Sm5khiM3z|IC4a;mq}_iD`cJlR4uBH8_9WLoDdy`fnNX7(=$(AZdji6$ zS`PL4Xlsy{3Q0*#>b(f%Jb0?_(J`K3 z$o0lV2Ozsi*eXAAy$AXUlFor?BKd1Wg_udJs0wkS2%=J^bKC$LJ_eqc)XMZ;eaKqw zHc$?L=3#hM845OHT29hmfW(ZPdi# z8l3@B@9xK{p8z@L%d~T+7Y=6&o}uKr0xd`}1*r@2eGrn#$cGkYln-rs;^1KVX?z=i z2cw@(3wTi!Pr5a&tzIhDF%fU=WZLELGl`+&F7JvuDWPS3)H_4#;3GJ;MX~qxR8$|t ztL4uIp|ilygndkpb+7QepE4{{wA z#nBWqY!BSe+(>kq>d%6)D>dv8^OWRAURs)FOdOPBu0!jMCcSV%C~~fCVN4YO(UsJA z%M&-vr#Vf~jyn4gcdn{q`tFNyk8{^RQ#E}9rG((bUTq?VDMYl{Vp}>=e|7jixPq#u zwKBtlDR>9$%Vo;lja4=yorem;f(Bz`Xhh2p(N&dVm`h+1c?I8=NxU)d8x^A)LaN|w zGJklr_ogUI_iLca8N9LvpunCXcK=KNy$xt|zy1Z=+z-q4tE|^AxNrWe1t_3~8hrj6 zk=d=AixTXgeLe>H9#4fB+4JdG!nW^y2NHCXYRzZjw7Oj+QF>3TQs`gOp~ZIlxZDp5 zD~~Atb0U~S7AHn5?aZN3{M7Xab?uT#Oqh!#lY{-4!I;DD-6&NJ%@|rGyZAZOsZs@P z3Ve(FlwW%!WjK)qk=!o|(UB4mr@f{cO+7DDmipjkFF3m2#wMy^s8Tz~Q9KAE@QHI^ zrE{}4|Mz9U_O5b`+`(kv*|$8uSdD!tSXe}W2$YoLn0yLeZIjIzz0)L9vztY+LmE9K zugHr4c|Om3t?Z`>6l@ud^M_^v`bjln$8FcjT3*B)8*`s*d~%L^o5Q|i4N(Q7_f|li z!^=TZ^I7o-t=&&qDmnY+@>x&f!|hvngR)e)X++t3F_|1EJ@s~~Ai(^v*am$$tEI&& z!KtGz+S7lKlk4SV%4wby1TyZLBw6r!+>f6NB)vpb-TtllrHu~KY5;D(8A;cT*xYsz zo7?dhY2+bb@efm)C~x*e893y(5_y6dFuTgOB>5-La9fNn#zJP}t*Aw1ZY&K62WQA` zu}Ge;8-z+ONd!UTB|rBCRG>_`8SV@!455QjNNPQw`fxUGkuPJX%K81{`-uflZCZ(H zznL(dxOS4_ITVP`Pm*w$3uDKiH!hD>!ns$?58;b|OMCJoh3ueq8@S&o>zWEV7%jiv zyK5V#{+`0&wWo?JYP1?jpBz$Pmm;%eT{L_5?QrZTlH13`L#K{?iymq{9~z%k*V^q( z#i(3qdLQS7Ck8cZ$qtt}Blwvj>Be{!(!0p=X=D<}<0;gr3{nxL3;jW=k>!`Cv|Sp${9-TiNUHQn_qUWXmZ>oR3vgN3YM!9SRYBcmtVG` zH=wJek+Irp-iTOWl-}XeHvoo(A`==_b`SvhGD};V~KZae4bw}Gv+GkCeKFl zaBFykyPTT`$woWr3<#7!(rV5*XcoyM-#vF7{yTgjV&~gcYib51q`7PvSO14iJb0F* z#Y~h-@>o&2AU%p!n&DtcQrd6;OBVp}h$>(5@Rj9naP1w>!EN@Iis(CKl7J3rQN*?S zAMc%ColC^A&nn?#+882^ambR5KNfcCSi-A(PI%{H|FXz^q7@&Hln&B<)n+~DY3wl7KL;Jt ziH_x)_n*^S>yp%jsmrN$*M{BeI&k$yfjm+)!2}yz;L4NY@(lsnGZ((>&^DJ96Ogg` zKp_1IN+{UX-nhJO2Bu;5APV?3?xbgPnhpHlQL zHoiRXg>n>Nc;OWGDY7~}^|)y~vl7V)e+|m&n}&~U%^k=u@|Afo$q?!gkWgnqCgk@% z5gpFduC_AOBSzEH;U2$!=*M%39=p%!vyE#ioeAQzK`7aY2wWk7Tyyk`XNVM02V1oz zgdPb!mlC5}`wp$gv@J`_jJ)h4=5V_+;c078m;6h4)12JbctVQ$q4=#;r`%^GI%&SOYWi;qes1P^n;?<>{4R}~%h@nwG(-Cm zbO;@OVb<<~wWP`xI%D=>>fbL>uCP}I2>5=P*fkTC$$nV3P%S z^O@2=yL1GkT(7UE^*t^XhAzDH(ENDc#FxPxOMasG7;k~;{;=@_w1)bEaYY(7Wd5r@tHhenf-NorkC&m<5uV(E|3%-x0Duo<$KKOG&z99MD6abW*;!K-SiEhjkE*FIN(Omx+q`?du`aLT|DkCQ-* zSz#SB5PK*<#aH>L)Hxo^le=U0<`BX_p&u0Q~hj?uAehR z?&AD!)S`yk)Vu$M=&3x@xVA;mbCKZp5FV*nf zyU38^Y;`o<6;JU%_@>@cRdsjTOEtU4gg2TfJ4&P?>MDlg#D5gXIU-J6^*-&%fM;id zyv}Z@bjX=JWnVc1n%T%*P6AH{k?c)E0n9V7>t-V^PJC`mLK9AAp%+Oq8@|v`$=AFL z&_h{OHfhi4Y(TBZrbZgvTcnG277F>;oC2?~3f{Cmk7?V;Zl!9TH%WC&wkw_uQ=|tK zzY4V)zF8LbQ3C0_e}_dR%^=0>AnJD1Wc$l0Vq0$EB1RVd?+3iKzjEjFB*=Mt?1(zB zPoUH%MvoI#Y1O*>tc@e*Q(=H+$1@U3ukrD88sdjSZ%Jkc#z$X^2*s0=3h_5Ic&yRCS0Hx_sWak}A#N zrQ~sm4oY+38V) zF<}p?a6oxq?RtAaG~uNOMcjNV#yJjpSOZe8t10gyE}W+?b+1i-y`}es*DHLPa;EYY zXopW~+tJL9>fLPJmZ^-t6JPK7UGp_VzeynN}O6(lmItQ zp(k^ZlKZ#uvM=t0~*4i6J3@0ym1!!F6)6q&(-%-4Hz8_IC ztFh2%%u}em<XOUO#^t3Ly6v@1)THk>F6MhH*xI|GjfOgOFdHpD#7v55PpX81( zvOj8)AEV1+bi{?CA|xoCIu<0%-GAc>%U&}_4{ff$uKKNBMPpZO_7^D9LjxypKmP4G z*!AovP;+y#8-J=V{S1;)Gq@|hOz+QmZFdsvM#tHBR;bwL!Z|dB%koiSUrENEgY}RO z=#p0frJMG6$nkA?7Gl#8o6dg`I58w-m}xS7g2mmi`g2DJ*pK3U`A)>(1j>1F_ITkf zsL6*c#J$j%u=?N&PhWmZ3ZmE@!4A^5oa26$V^vJH{#rDW zY7@&n%MenaoHVxdp-9_LayS~#mqc;9screA6}aTODuDSWWR)dt)aSJLwBP5=!}=?5Qlv)G@*LI&N=Yp52P8D!qjK7Zf8{7>!T@8U zl+M-P`(y`U&(B_d)-jytL22y&GDZMt!SM1UYMF3L*8fF3B3(`aSV4v(1I5m%N*OmF zBgr+`;m$7c8^2}!7{bM#S9T%z@r@FgSvwipiNh5~)o`^b0y`}OZN z-nHE?&8+}BH#1*pQuG+b!W7WawHoYdINknuAf!L039Z!*x#dukp!@*LXEt|{^dxoR zm)DbDn8=d+eH)QqMG*0y-Av!BbO>ZNb{5ZF6+d$~ftjteijR~WM4;90t2hx`1Y4n4RGZS9`tU&1NY@*W^txgF7iK_WxwQc$p_7jP+M_K$q>RJ8~u+a@L z?#0E-BC0J7*PU5saWl0oe$?>uyV`p>s)0}QK0J0jb3u5yxns{COoOgm6!uPah)Dq= zT;xlg3DG3mGGpYTfnxrCfk#85{e0UWw9|=gkL^NBe`<3<{U6)yk%x>t1M0D>v>k#%DM_&dJFpzPIA?IV z*{G2sfd5=wtb7kLM#(R%k8JL zqy$r_gYbFqMBhPZ+DpZY@j?ZiP16;i0h;2`*ZcxU{O8eg%*IQIgSiq^F6&Sct8PmH z=)YtuVI}{$Y3TKxFEd?%aGE74Nl~D!7-mSeA=}74q@S$jVJi7wGLs16k7_%Lb)h-S9|F8s7f-{IV#SY z*b{E&unJz~rp8s~9Y!kRcu(a9jn7h`0#h1nqIBJ_L7M1K1yBZ&GWb zB|}qMfrjjW7F^f%a)e?S z(8j+g;?R5VG3(=I5d_=G*afIykG-WfeGSVq{)dh2b8&|c7XJ%_0_u24Vij!|n8z-3 zwChTt=wLd6e0K;`W`+C+xqkebS|qc`z7NeJ@As@PlM z+jH)wR`v9$TqD0FBBTGn#I{#IREn(;iFFfXey4M>cPfKG7AE9{(o1lKHgbj%tIR@= z0$N3b`t1_R5+h4r-KC%)9vxzj_1@tebQ-J7yVG1P-WL4m5mNd2=Zi@W%G^<|+ElH6 zWetUuf+Aje{s_%oaiui;CqV~akHtsRu-kcyl&0}9=v8PgJ$C;%g%S0--j3LUw+YEh zSnJ!IMRVON{7Tp}H~2|02BmR)bk~o0p%nT*eoUsIC@(ulHOIgtx2Y-IlibLQF&yQD z8dD#fQWh-dT6ecM+=qoO)wXY-L`rked|$tx{T)n^3tC{y_v~Gbd}qsw>{MwoSw_F2`0r+g%>Vw+COMc={;%;H3I{Ug-c6n$wn(2y3f%j{0t; z|ICZdQ6Jv3W&V6?@k;c?R0NJ<#nKk^E50Xj6qE&m7zzKc4xZC!O2QGd$=N8QQEz{= z(lZ_MB6VzR8R=&nfg=0py!jGdO{qyTr1%V2xje!8Qpa&i;siFK4WlGc%10D(4^8~t zn1Egm&@1A%PGFMuLx;^~l{TOcW9}q4>p!w@36}$Zk*+Fzae6cnHW-x;4p0ejLSoPI z;gN2$fuKMQ)@vQSFi+1m1OIQ>O@EHG1Lf!z8%$6AW@#w|SRn^-2QN`nBGd(JFQjTp z92sdW5!_|I3EA-EILMUUO;@-W-eh_nIBg%7^W@ZagI&bQ0z(1VLp6bc&}ZJF-XF)NNexPKys_%y*$_ya;$-0=_#9$dm@QJ3E3SeZasI_10%imBrb014h`^pB^=;LU%G0@g?TTu-v=Qo>Y#&Lp{5*dCF-0D|=2e*M zBBx9DXTCX0^vqpkEW^7@+nsiLH8$#jABepNX{OJ4Cdl@~9ySZ@3b{Hk6uwi`E&8sRq`4zkAUu)MhD@lHN4|<7Rz{yCAp2_rGBXANLiv5wjEPXsq7G-Mju4r{8%NsSB&9c@y*u@j zFaUlhmqF}JN#PD|`#cr@>-hkZ+(1w(-cG=0HV;qZY)kTbLCGk@G;3W^^q+;xgkTi4 zFW=dcFy>l75-fxqck(oM7m^x1;W5=jtmoyA81bCK58;}-LS2C=V9*inP4&F;QP{CmHaa#RyuGolhg6=Xc6?d^b_PT`GlFy{K z#p0O{Z5bzoi?#r+-2~KuCMX4eIR5t0r45LKdA0%Kr+xQ!l(rYjfkJy-tI_&K94}gY z&e(fXGagy=%FmNkZ0N%eq`aoIDB#;!h>F8zqo{o;#JaIqsZYF z&RwETEybd_F$UN`l=xJpFEA+9{IS>da@zG?ZK=h)5`Ly5yyI!I^g>ny^<&(g-hR+( z>!=q&A@wMQygNY#xAXWhb{lpJ>>{ch*F3~GLLRsrrcXfr=1lq{BjSOlB0^8}eA0)q^eQjOhM!xiosc;)x5H=TC?1t4>Osrr;|BEne$J5Jobge#q*}pCowvv8E2N?!$D-{tYb}=%D0?Z z#*PU((F>l%Wsp^T2DjW5d)vIsKqF1^XJ7|;ca$STf6v;U`QM|j=LEb~@1ErURN}a*Dsh-bk=iiYtVyI-SSsBGOMWj$hX{L|kULZnFY{1@TF0wC$u0=X z5*{BoWDU#G?ZTb2Xw#w+c3JV!+q`thpi|FX2tX^;{{TVqiAdbW`Guy+nQ_)*=KYN| z!vegS54yG@khS%0RJMcl`^iz>%{u}_+Nwi8D7Z&bO*KgkEV8k*Pq||3sfMkUWQ94Ab1d5lLs=eXUi@fctQ<4$`uw z>@<{Ht}1iKRG9viksU-oq(Ei5S7=d)Qd8q5H)fgre9!gT%Om*gr-whyX#9R*az60& z+w=eT|9?`md+e@&rlu2T-n*LNwn(D~e)HQwfCuMsRvkE8JgW7-ud)OrS)w!#3nl*( zDF6M<{4u!T8=d!a{e;$S<0TJ*j;;us` z94t`t4$REGa2?p?RQ4%vnvFZQI?=TMc+HjVaZ7=*4C}z+3X)1oUrn0pZ^lCG|EK|u zxCxI@>`g(>$x{9F2@p`)cE>qn!|2%eagNRZeUnqdNEDv0!=B~~#L8atl0R?=PZ}w& z-CSWG-b`<=uy}OQH6{!3{(3B241WKE>ekw?8~au^=UM{1m1~oT2ijM`GbQ~NVl@|m zB!@?H>Yf98bEr*2DJaLBKc0B*zd@H&$_vC-OQ#fL%mYl&br8VbDQMd#_}%%ZryB7rMl z>Z$7m<+F&Rw9X&gBeCni+m|$IT^UfAqv4b{L{UICDqG3b_#31~?+>pAH)qw53VKOh zz9VDw-w(ORh6u}tuZmsbrBO(mhS5ac;1!mS34p=I2%lC?3u^*r;_3ZJOB1Y^Rs9fM zh0f9ha8uXexbuPi)f;+X&sW|&yp3>SkueLCTVRRy5j=IX%Bvh`G}-E>7T5<>wh}01 z%(~)O#ofpq`19+h`x#O`3*hc14qVvrDl=dG=o|Ks`dw)ZLweMbvz& zDwb8rc5cy=OJWLu4|7{k1dSPp*?f^rpesfv5!AT;Ah^ND=xP4|Hji<2D~C($ZR&xdNeN}CQI%VptEK^ zD!jv9U=hQmcs&+`2xqg4lcn_qj5qv*@D`Dns{!~@IT9KYH;s+*}H*_joLSosj! zbdVcNycgolw17Nv62UKM5@~g8B9!4Qn`vpQn4USCH5(F`zpF13oavz!*=MTD{pmNv z=0iV8NNF5{VAO>~<@lZ37oD~>MoAuNsQ`kN-&}xDxV85+}<-9*Eyo^>B0s#PaFof2yvvr+E<+i%ws7RbvkCUohxH+ zINcoLi<@hTM8=7*m|8x*X1W?Y+BaRgrF>~4ZOL{Mod<5?4z6DiPUYY-C2YgBy%5LZ zuxNskz;E-rhV0Ina63HX&*7a1-~~b4?BjkPeWbx`dvM1@urc13rQ?C%5JDO)c~ z&h`9~XSimJb1WI+Fga=LYKpkFCHPQKx7bkfS-nO}K`=XWTkB@`*wPop-<%#%5`4V| z(oslVcjV=j!F+B;rPwYtyABHbHa~sq2-EQ!5PDy>kCGe|xJ5U!1KyCFA*3`@q5VaP zgy+d=ta_O(=DjvQQNe?*MZ&3{1aqN{i?G>VR86!-He0C#$kw8dXGR|*^5?CB>Fn`d zDGb^br<#XmGDbs99Fj$PUP8VOm8!Z%CKBe^SREpAE_|rAj{<9S51A>NYQH3IrM z40aK2ZlkY*HRq+n@$fY|ygVFkaHq#f3@W^%kiV2(U;-~G1|=9E@6jR#WyURcR}TVAzq4c&qA$gYFgR@$L(Uuc}eX;YFkUUi3v@IPfn*Ayqo zib7v#bT|}iC-R`fP2x}08Fc2}e_d35;toHt#mQo9m>I0PjQm@uEB&S21AtLLuh(tTIyf_Vts!|F(LO); zx6@&Q)eZcoJ>iP{Mf7?4zcr8l`HTNw{R?5$z-dShy$}UG?5DVZBbj&a?ZY1H24}c0 zIF(|ML&Dzp)1hA2``*LoBIh5*P_CE+C^^U89N%nA~LBG8AXd!;d~LUG~!QylV#3Dt!jPz zc-_S8ksDt$l*=<)HX)>KLQ;s6dvMyh)KVb9G7@D4!uS#UnCu1bJL3jiZHPsy3CbEB zZj8^#5xd zimyRW^InQrWc1&+J`CRaWs9GnH1~!PHknOujI7xz1i++KUvN+PA|VDM@&>i#?#L#;J;D2!d0ZTV4CGt`3I6BG6=nl{g8trM0P$KS4+e z|L(#S?3;Rzxrw5fBg^=kC{ARe)vsV=Fzo0VV{eE)>sA1$jG*PYjd%yR=S0oRGXtT; z(r-DJ4Yim?2tY=;Z+vOJaJcW`(2Nk)J(I`C9jxVz2ss-WMdjCX-Pi`qUP&Pr{boq_ zBm(aOY`_h|6qcwa_}HwWQ}DE56U5ZZmCavI8Mt4juccFfiq~y=ZjwM|)9(=CogeK` z-i7W!ZOayjTi;!DF#dTJ!l9OR@W50B>5`CWu*gJ`+3PM%K`Vo0#^CYo23&dPtAjT-Y~n;B4tuHs zUPY`}Um$LS>*E@nhK-0cZVfrUtXRM2DTCT{Eif3w_4C1uOvT3kQxrXDqn7$a`8y|E zLn;=rq*F}D5M{*HCWJ!}4UDYZ%06C5&<2;kZ3V%{B*HAhiNQ#&5nFu!$-Px+i()LL zr;Nu4o(3Upc%Fw9?`h!5cZ+N>-m3=TMrLaAPVdulDGcS7LQFrJYuG{T{_>}?(Q$i- zrysSnF1X%+6Itv{>>#EXe_hx(KUZ8c<}sgH2Fea1r$iO&xD!HD zOj(ri5*+3)AKt4*2BfG*BS68m@ENwZ_s?|aa=SoBQiug{`0x3Hi6A3R^H&>4NhSb; zwz}QSE%cxU+Gc@!$}lxGe#b`PS1AQR1qY_A(&O4WJ;C`>{j0@)}>!yRMCz^@JDGj{T^LiAhke=sny68Z>XNawMIo+i#^mPmf%s zlGL&elbkd$(_CQ28;Ca0)LW`n%;Mwcnl$;5SfR=hDAd&+8+k3}uFnHcTJEemkSqy)9b*=$GoxlV7bdv_qV2 zu^VCqcj#W;D@C_z?4TR$j!^hO7DUY*%=0}jedwj*?WK)>>Mkf`2*r~NMC7#q#;s<8 zg>rq*-`*&KXv%0#&onccIF2|Atl1LA(15|GD^}ge{{}T;J^oJ_XVG%YrK}|AeGTihGrLQ-0{X zQP&m;tLul#*v_}p`F;7HIuD6@Zw97ZW4eD$W{1~_U54X0??sf?=-br0aZ_?5Uaq{rgcMjvsPo0^DMO}^+Zz5$i zbrz(AyEgkZ<8}a(*|-R{OGHR0J6u}N^zlYx*9R*zizU4%&$zjctI%1$7NCBV!F~Sz ztHKs>_t~H^StlpIc4I2;tC3%%-5)z{_j5We%i?G80YT&<7-_64$}o0-vB-^FH`CLI zz+^%kKK*sLcxP1BIJa)8R6|m2y>C3iXbCCGC-K`6qG_?r;UUIry_W|k^-Ud)-{4?* z#VtY*R%*{qANbT1Uu`iSQ%)WjBdhK(WSj8k$|XLz@Uf`W0Em&+o?$U4<8(Zx zUe|pbC&K)Z+swpYL;aK}S|D2qH4~;L&cvoRR<&(OPg3waN$)JYlU^nyXKq+D8h*IX zpp^C0j^oim*eQX8o#IC{i59!-ZX3N}ykF6Z?&RwgD)9;16(lJV+a}Qq68Jj(!9X~W z9IF&v-(h=CC#H->R;}h6W1&zo1%AJ%@iWiMAF9x`+1vU2`tK@l;C+$fTTC5GH`dqb z>g7msc-d3$^{MY+MF7P~Jslo;4eh@7`L~W1k>xsNin;d9L>U>JkaMZk2y=1>%780h zfA^-?FOvPRqQ{xWa+Bh}N(|Ry8I)dnjGX)DElQCjDRVD88EUt5)>4j&yRp_|$^FP-6SvQ!IS!d@-7?%%GuffJZ^iWcb#D0CUK{5n%;8FuAw$tA1OM}uufHn42Jh@^ z3zNCO10w#@LLLX#T#{VWf9uc(tL-hEvM(D2-$eemrE`#y33xpw|9|~aO%lYdZ;#&> z68LYO>)^VJN>u;t(*JuO-jL7L{NF}3bFckd*Z=3j!pcE%lJ0Hrfb#!UUDjK=Mvq+L z|9m-c!^c{F!R)l&e@n0j7peJgBKbF+gkO1ApqcG3ndYSV&n5kPg$zpX5i#liepw=W z*Gk4&#{Z+^ei)w2@R7e)*~1tH5#C@BBv43U^yTZtt*=EOvU(kaF!up#rXMnqTnkyu zdaQ6hUi{gP-AKWksJ}lW3sE0>jv4VIpGTM#<2alxAArc@`KtlTqgOZd6R3d)L@_I* z{Hy(|kOI~t6Gyz) zC*C3To?z%+KLzfkeG)nkloJi$9Bl&RLlZRYK72@8<#NKP+tDv-CD2#$y6Q8B-(~9QX>SJO`z3M z6Y`o0+P3y>C1ve6d0R%^`tLBb6c1QQQf@D0Y>+Z@k7}6Nol{wQU_+5YiQcyM$!eNU zGnjx-dl3n~>+CwI82OPoOnaabv_^&yTj75pa7`pPmUo*_*zV$VuczgdgKncGXz-kb7R>@Ae)j1CU#|nO zwh3bOh6p;P9%K|(7qg%jVR{1Ols>d$UAp<1AN#YUC(*iGseviG2hJ9PdKWZUUS{4I zQAY}Oyc;Ax0H2Co3SZE3vT*KdO)( zEiyWuL?2v-6O!Fr_Qk~fU%vv)@BeA<%cG(0|Go<`!k9tUQDf|)6f#Eku_W6_5|OQt zJwu5?CdOLQLiR1BWb3j-*^)}ORLHLERMbRT?)O*M^*i_Pocn&xbDrni&tK0u*XdlR zkr}?<@8|t~zuvD!9~_=uK&0?6K-s=oVob2WP*1IyxIoVUdx|#89wZX93*SrIq&tL3 z9jFhkECC}e#0_mx6Hd5RI(FY%L~~l2AV5Ohfq(mwpu2Yi*N<30Xs`{QC8@~csU5#b zH`?6@{5FTcjK%a5?%YgH`D5N3F=xH!{n?!C;h#(9Y7wekhj)K8^YRqG&BW+3q3_m+`nv84Wo`X3fm;K z*OiX!kT#Mk;Me4x@f<^f8LFE40E`U>r~lBojP3Qt_5*(bi400)m+qZ3a#?B9s5t|Z zC_xvAMp$sO>;V^Ap9iXBYRXQRrxW5N9@2N` zjdQgJ;jk#bIaSr7&&n7Of1L}lL9#0J2%Q5t&kEkl@3Od*3~U; zSkC+$geC^N%1$zOu@6Nz`ZgQl{BWCDnFnv5;Ko}k#^m&y zL5!kMB19;-hcsY)DyPC~MnQsZa)okGIfSv0PeT`b!g|#|gA^z?@lf~G#%Z)51s8XC zzGPtI?8VXrNObnr&AJgmugI2wRGrL?X1t(dEZ>1wFetSqzd3YQ5IQx@1<1PqT0+enf1)oKJWz|dvVJ?CuZZ45J5<=h~79xn3(uR zMgbXTchjw|0Pfyq-G;=a0|I|~ z7#g+)%twzw{TT)TYX*q1ONb2ZEx>TcnAeeYH0ZWnbV290k) za`_=RmwiL?761VYgq;-Phi6~-m5W65w%V7`xWBp3v!OKF2ZERPZXD1D65R*k!g$Cd^bDjubE$)!uy4RH!r5br`Ps}7{tp(b|1Au2 zs}{wFhbzoPyKlGwnC-*h&vk=uCiH&l-@r(_2GUc#Rqn~;=&?+L;nE&y!9qpNzyuNh zk7sjQ>=>}(eu%)QC2pVB5U3wXRweT?xxl^~A>^XBkpP#hM1nkHXsleqHNc#^wR#Rf z&5m-dv2f-MvoqKSxS6S-H6DKiT#_BlVxEFCpGh0#uX{l+X zz*G7CaXcj0W!*0L?Wy+<7hoM4DsNFts#-zm2MOxfrEHv{V|WauRer)1nDuRG4Q(~p zRK)FO@ldbqcxNbf=oiV76egcyhm^#V!u(w&mh3K@zGnN1ou{Tq&% ziY`vTd|BQhqJU}e<){IQA#p0^iuM9VX#B!67&BVrWA)yLw;#4*nSmf-Ds)tT8F5ms zLr?r4T9Fn9kA0%Q!{=h8)2Z+Pc``?M{l2!5bIvm@l^1hhXKzFGRC`E- zou3GMpRC>lGB=W1%Z1 zgq`4y+Ao(2)XocFSX184~CW{%*6(b}KZl{6A1mX3Ivg>hE`j0#<${1eW1BXqQf_gxj)#E#7r zBR)A9MM#~@^P{mJbpN7szd=dNZjq#@_>4tQ#RxD>1Z zDHam=@cwLZ{#jQ+^!`BMz6DHA6V}kkaZQX$pSa?D>2q5HtOt>}PPALbIl`Re*%#*I zlW=C-u)YosC9e>+ui89uh^&|!KP?{QaAEBPI1Dny^-H+)T^ypmGTj$MIMGB$V{t6Z zvex9SyI?py0y{8o8bTs)`YIdK7Lko4TH*r8Bu^KIiY=N@R@(F#W%4?u^D&G5kH+y2tE&1G#PashUmX}PB;VO>K&lel)zfYfq zL*`@Z&f;L?qF;oNm_wgDv#}ec$eLH%^s;@S09`qzn;OPi(Yu_e$r6Rk^o9~=P?qxo? zT#ooOE1BLYqmLyZZ__{Lw_H07^RU~K-}@tN#Rw*3UAn=Q+fTwK%Xsw(hZCxH=IZsa z_uvQ}7~lc+l^d{7mBk0!0uKD<2-$GoD~=hSX-7c8KG|)$(9?I8H*7j$*#WEu@1X$^Mc3h@>bYttcaU6cE;}9$9MH+_;trz!~{BSr`qW$x4zx8*0n5TBNmmS)FZw1yGKI2 zV@}Oa;6bV+X%{MzITBDcS}rX*hImSu`BPQ$)+Chh)=#0W+g%c4<$A_8JzgxFG}T z>F>hjYzQ4IPO!Wbx|l}=Sv@x4b%frZM$$CtW-hU(!p-TzGP%jWNTi=@rJfy|{hv8> z&8HfuCD@0-*g}V)B~SE^c;Si)3mA~#aL#`Z1U>NDp{lpXD>ufQyM!x6ZPF!DMbD7? zE*vF+#9Mk;)md!7N7-e(0KeokF?l%0#QS*n-E9^5s?$f6*xP$Mbmxp!#qAIKOhtHv zzDo4H%kN!oR=7Ud(*T2e1!7PUR9bTKkDus2P?A2PC`fX+VCwL1*wnv&wTGm(-3SN@ z`fF9*xis~`W^TO$`l^?M(yvq!Di5DEa8j;|>FG&e7WdeL+pl;PZBG@-n-{tlKijNt z_<$-nc@CJ__c8*mNru?>X`Ci?Nr|qQGKAKyPqb&|zZ!%Bp}XT{usUV2{wG^$3f z+bbk=ndBl5f0fub15ZD6P{AZ&+NS4wM%Jucd+5*LBeS@Y%)?cP@Z;XsH(ndK#3;Lk zuO+Ah)TIkxd=DC7kKQ%)#(gpl)krz_KFM%lKTqeKob$VxV*ly|iiHY)X1E*A zkD5>(7~|ZZ52!C3u{|eU0ZZd9TUw=bF6`2KD?CoGVFsgDGTeM$*{aJ>SgnWn6@A*dfOg(gBX;9(raNus0PJEU_}0{PZBzH^D_=?*_G ztklS^Nl-INxMgiLxK&-wzua1RJFTHD9fJI{6Vr3}L3*>_n=XI=-PsI&!MBvMB_3pT zOAR=IafMkR09O&y?Q~ZsCo+2+mx62_GoOigO?7O}bZWy1vawN|>4r3`YeZ**PR7O)ns_%iM$UaRD)7!eJR&98qfG&T58i(Hhb@dd#foH?+-@ zw_mEd{ggQ815t-w8WT?w6k7zPCns@PfCCAuE^Rv*Jm7ZsIKhP*EvVRNnn6jF0+4uvPpdOg8Y!E#m>4v%|F2UnwBs9=X>t)50_Zk3M)o_ zv^(sB!e|{Slj3X>RHa4x?gxrans2Y~YLsSvd2%q{GknxWJ zM6}SYkGA8qy~b?J5*;a7%Nk9RFF+O2mrf#mrRbay?PBEKn5!%aT>)iM_6-g7w6OW-7V(j%AmuwUB8Es!iD00HT8Y_)T|TJPk8|^8Gl&tKjU73HEaU zgB$jmvA_j8h9px`Aky!~>_WrMThy=vfJn`Xn`>^Mk4#JqUHAi!;{9b968oYNhJ z0+O*aV-^$SLvG!Cm}Y-$*f#JA2!|72bAPsk{I6VcD+cbS>dc`r%KqQ zsb-YL`+HiQ=d8T3y3>I0#yxmyQ1k<4>qHfFh);iw`k5uK9-h%tX(-;W=9Hwe#bLLO zZ4pL4Q9b-*sX$4=i>#E11dW)<%cv&5W!^n5MD?CkLC&Pwi11;w}i*VRWDja*H%_+C0n=WG-6c=LArX&Xq6igOK)6CiaY z&##TFQeW+HX-jcrjG8;}efk~edMbtRc+>Yh6b+E!o;QD%4MwsN={SpYqu)`g4m0u~ z=E)WNktrOW9zSm+p4TlTE*Hsc#v&<~+tPs55yZ--hu}Qpsq&qVbhPm(*jEo?n%(PlVA;6@*_g$6RN4I#j_rCKQy)PE$BL>QV(QGqVrYt_|dbTmaXYu9rj zQxK5S&yU9N`-kNo*o!sV0-ckU#cK_uaDmST3q}M1W;BC!iHmAAMx?mTepf7VYXEMw5J2ue` z!G8@}?CQInGC^JyTd*=Nf0YnbL*GjfB)idb#{>^OzIK;#giMQ_5#~H^ER4MfGp~)Y zu$giPmiAdUdUUeN@O7btFo$j-Ft_$>Cs)wlV?MBl_LiL6X?p=Hyni-bi_vH7(FQQOh}UFf*-tPZg||M7T7vao@x zB#1B@P{qcY=jkDnU&Qk3pKyqdoPIT!TEwZ}j}o8yC^}5ubl__af8>N8aK6QHzF7v> zXOxJ!9nq@aLT>{mZ#~-dqv*5KLVbettw@x_Ej9F)i84*G? z1G)CaFj$L^qwERJcX#A6@#i;`vw0A;*L_mM<+u<$f^wYgPuJ&u$E%!KvWkK#GGf92b;na9Ai9&OWN8Z@)3{%pUH)!t5WJ*n@t-zdt(c9dUQM(+7pNT)8k*R{} zXrUgl-bBCmvoiX&SpC<6zZajHXrO1UslIw-jD9m^x>k8JO37w?=)1Bc%eGFL1{nt4&@px~`kwTnBAkl89pUy8PXFTeFAhCs~vq z;x8qfkF_zYQZ>>Mmy7v?822ljW;#>HLkLP$#fs8o<`?ekX}>DkoYd&x7*_F%sw2KP z(jxnYyu%D_@%$qWx^bJ{OD<1cW0?tAm|2ctd+W2a%fromU5|fOUE<G~3(fkS_PIxYRzfDe1y{JMHzylU4zV7KFSj8Oo2WL{ud6$0YY!en94m#7OILn$e9DEE*@dc`w?laCUlGHvy73txIO=>)UUZ;H z-eE-#2kNnw8D;&a@+3=2s41Hgn#nY}r#z1Fg!(qN!u5V!9h+!h(ZlSWHcr()j8~k^ zdkc2S1tyf9de)aC5n}J;D)QG;*wmRD#(9%=^*W?6-u~F{(JL{(Z@TNDTzo)pN(GYP z5p*~2vXsqr+`LWA8tUzcKuzJ-K+i6*)X`t=D^a3#LG0^yA zzOyU*at_UX&#L(9gYqdya;M<9^4Y($*-xZYbWjRrntJw)pkBK3VB)L4Kvef%j1*jY{+|K<^>OR-Go!1b^WP`zW1~6$YnsT7+~$@% zM%09*LeOs8)zjKyZBBWJh&d*C#o>vGP(UD<;zpFEI%cnQXQ$2r?{IuYQNv~Yq&mI5?V{F47=weZ$guS-+e;1VCvOt`NYEONgqth7Mo1^rCHkYJ*_;V-ko)UPxtje4 z0PiW_?4gO*Uif(~pr(a}j@AH-_Eqba;ch=O>~UgHy~i|p4X7Q>XkVPlscZT-SI+}C z;H8eFZKO@^{7qHz=5H6s8fMXd&H8wMl6595+@e^JRStCnYjm1dwJu zcd>SibQPg3HClk}(&;i;w|kAkhN9SrqI}P^$LOTyi0cT_too7Iy+6zBC?!fz{OT6& zR@ngUDm=a=Q)HjdQqy=T-8kKAXw8Q~P&^D0JyFu{jgf(f!gev`ykF^>i0|?q8o~Fc|C_v1aTrpc z^xD2xsBO0Hm2FO4Tq0+HXs%#8@ll^P3oD}7c$z+YhATrTKp$_ZrCYTn>3}_ZRJP8w zvo7WntKzz4kY*z_B(iWXJKRZQU?+@4m0f!b-(&;3)y_WptTPwA)#?2AFMFB{B_uj> z85hhpTmkrBPp<2Jp?@dFx8n&c<6F3C93kQDPPL~$$Y0fWRqEO9wsfrPTU%jTBJ7kN z3H(}r7RU4}EXjoH(0c*xFun++A`A-usYSAqSCW}yd1psIwQ*!X?&48p+UTLttI7Vu zusw3U)QO<$egqi`R&*%=)l4@UADXmr$#>~FwrO(&UfVC}lp#yp^k?oQPJ;Nz*~kXK zk`HP%dwi4C>xf1fT9KcQGPCg%UR51a6GAIbN}7Izm7Q`#cz`gUBJpEKLf_taJ_*Z2 zBM%OTr{`-DRez3PP67fSQ}9z#m^788U zvCdfZzJKXx-$>VinZ^g9Ys>rzAecN8uQYp_9JDGLxNqS+O?bX-aM{js6&A zE+9Gg>|1l#|7wt+PAr>=C9#bNCo`JUf^b$e7Jfd`i<`SurDLlbp*a)Gn!Z={af-$p zlN_b@>|O9FjM2_XQ{`qi1e+&Z18m*}{}c7J5-tJbWE$W8baH(4Fwqyqeu{_KG*b9~ zFia%NT^G@tQ3krzDQm@%W!`6E&v_X`V?QG&rEVDv9_z}~NZzjN@a?}JCF0LF3nT2^ zF5xSdsdx1k&oj73b?SaOg=PVY(}=B7V;9wYnnG9R8OZ&`t-1f9W0ma@#E?Q6NE(IK+ma()Hk3T<#z5;<^nk!s z4je0MbzLg{&s?!vmu>R_T32CdlT^olfsLGlgJ9hFhma5+2sP5fO#=6QqrssB!vi}MTPpUI`adyWRlesV%p!%Ig@E3tHYViiqM0*51B7yA(%`G$GD#bTSk_SIRa>elhA zC{aH*$2^@im&$GF_iv}8lY(gC=7zGp@qSC#6U29PQ8H`dPJ?gz$Sf2ITwvxw-f+dp zZJqbb59wNrF9c*Mu85WwDL8xOAI9qIx>`)@%n8f}RjoV`o4!YSiN;9hi+;8qIUcPv z58er0D_(C(Kw+5_*VW(&n$N`j6a}(qA}O>b^TmqC8;q9Eb}}E`eS5Jb-O2{m{-o2K zwZm>s_HR!Qeoz+A9@rx5wQ#8QbpHtczaJ+Kjb1Wx++C)1G^{Qgo2nyYaS%H6W`^eI z7P4f>^;;ruXxA)QjQ3(iYY6$lIy$zuk#S;A8}tyFhW&?bwp6C7Q+D|-=sDP88j@qQ z`L`iYjHSqW!u3Qyw`+eSzuQdHM6ekfb5_RufW4Dz_tgveDo6y#7E%8?jO@)>i ztKvypxuBS(S>SQH@BXuzaOH|H@n;b4N0Tzi2H&x>&N?l{Q@9+mftdQG`Qm-2jE$NO zy5>J$v+gd&vE6I-*q78^l$^sVkzvq+n#+b+@GxaOZiu! zt(Tjf8~Ias{`Kb;UGS^WE}PH!*Wdj4pJE9Zla1@@s{ie~)3qaDl9RHf{1fK-RJP`=k8N|0q9pw70hZBDyA%;H@_u&^IHO>N;Nh4;e%)NdN!< literal 0 HcmV?d00001 diff --git a/demos/img/pums_tracts.png b/demos/img/pums_tracts.png new file mode 100644 index 0000000000000000000000000000000000000000..feb3952973dfd4d7176512a0bdda78b654fac389 GIT binary patch literal 9379 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 literal 0 HcmV?d00001 diff --git a/demos/img/subject_table.png b/demos/img/subject_table.png new file mode 100644 index 0000000000000000000000000000000000000000..e80afe3729fe0e2813a4113268ea6ccaff7a04ab GIT binary patch literal 52276 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 literal 0 HcmV?d00001 From c7ce47735fdcf35673626fba5c5c7bb6ecaa1f0c Mon Sep 17 00:00:00 2001 From: PyMap Date: Mon, 27 Jul 2020 10:31:07 -0300 Subject: [PATCH 09/12] Constraints --- demos/Synthesis workflow.ipynb | 775 ++++++++++++++++----------------- 1 file changed, 386 insertions(+), 389 deletions(-) diff --git a/demos/Synthesis workflow.ipynb b/demos/Synthesis workflow.ipynb index 90bb055..32b7013 100644 --- a/demos/Synthesis workflow.ipynb +++ b/demos/Synthesis workflow.ipynb @@ -60,7 +60,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 2, "metadata": {}, "outputs": [ { @@ -96,17 +96,18 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "# These files looks like...\n", - "hh, p = postprocess('02', '013', 2013, '02/')" + "hh = pd.read_csv('02/hh_02_290_2013.csv')\n", + "p = pd.read_csv('02/p_02_290_2013.csv')" ] }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 4, "metadata": {}, "outputs": [ { @@ -130,6 +131,7 @@ " \n", " \n", " \n", + " Unnamed: 0\n", " serialno\n", " RT\n", " puma00\n", @@ -139,7 +141,6 @@ " BLD\n", " TEN\n", " VEH\n", - " HINCP\n", " ...\n", " hh_size\n", " hh_workers\n", @@ -152,132 +153,105 @@ " tract\n", " block group\n", " \n", - " \n", - " household_id\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", " \n", " \n", " \n", " 0\n", - " 2012000184237\n", + " 0\n", + " 2010000910239\n", " H\n", - " -9\n", " 400\n", + " -9\n", " 1\n", " 1\n", " 2.0\n", - " 4.0\n", " 1.0\n", - " 32500.0\n", + " 0.0\n", " ...\n", " one\n", " one\n", " no\n", " yes\n", - " rent not recent\n", - " 19334\n", - " 02\n", - " 013\n", - " 000100\n", + " own not recent\n", + " 3972\n", + " 2\n", + " 290\n", + " 100\n", " 1\n", " \n", " \n", " 1\n", - " 2012000184237\n", + " 1\n", + " 2010000165017\n", " H\n", - " -9\n", " 400\n", + " -9\n", " 1\n", " 1\n", " 2.0\n", - " 4.0\n", " 1.0\n", - " 32500.0\n", + " 0.0\n", " ...\n", " one\n", " one\n", " no\n", " yes\n", - " rent not recent\n", - " 19334\n", - " 02\n", - " 013\n", - " 000100\n", + " own not recent\n", + " 3972\n", + " 2\n", + " 290\n", + " 100\n", " 1\n", " \n", " \n", " 2\n", - " 2013000404401\n", + " 2\n", + " 2012001118337\n", " H\n", " -9\n", " 400\n", - " 1\n", + " 2\n", " 1\n", " 2.0\n", - " 3.0\n", " 2.0\n", - " 33000.0\n", + " 0.0\n", " ...\n", - " one\n", + " two\n", " one\n", " no\n", " yes\n", - " rent not recent\n", - " 34694\n", - " 02\n", - " 013\n", - " 000100\n", + " own not recent\n", + " 4164\n", + " 2\n", + " 290\n", + " 100\n", " 1\n", " \n", " \n", "\n", - "

3 rows × 32 columns

\n", + "

3 rows × 33 columns

\n", "" ], "text/plain": [ - " serialno RT puma00 puma10 NP TYPE BLD TEN VEH \\\n", - "household_id \n", - "0 2012000184237 H -9 400 1 1 2.0 4.0 1.0 \n", - "1 2012000184237 H -9 400 1 1 2.0 4.0 1.0 \n", - "2 2013000404401 H -9 400 1 1 2.0 3.0 2.0 \n", + " Unnamed: 0 serialno RT puma00 puma10 NP TYPE BLD TEN VEH ... \\\n", + "0 0 2010000910239 H 400 -9 1 1 2.0 1.0 0.0 ... \n", + "1 1 2010000165017 H 400 -9 1 1 2.0 1.0 0.0 ... \n", + "2 2 2012001118337 H -9 400 2 1 2.0 2.0 0.0 ... \n", "\n", - " HINCP ... hh_size hh_workers seniors sf_detached \\\n", - "household_id ... \n", - "0 32500.0 ... one one no yes \n", - "1 32500.0 ... one one no yes \n", - "2 33000.0 ... one one no yes \n", + " hh_size hh_workers seniors sf_detached tenure_mover cat_id state \\\n", + "0 one one no yes own not recent 3972 2 \n", + "1 one one no yes own not recent 3972 2 \n", + "2 two one no yes own not recent 4164 2 \n", "\n", - " tenure_mover cat_id state county tract block group \n", - "household_id \n", - "0 rent not recent 19334 02 013 000100 1 \n", - "1 rent not recent 19334 02 013 000100 1 \n", - "2 rent not recent 34694 02 013 000100 1 \n", + " county tract block group \n", + "0 290 100 1 \n", + "1 290 100 1 \n", + "2 290 100 1 \n", "\n", - "[3 rows x 32 columns]" + "[3 rows x 33 columns]" ] }, - "execution_count": 5, + "execution_count": 4, "metadata": {}, "output_type": "execute_result" } @@ -288,7 +262,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 5, "metadata": {}, "outputs": [ { @@ -312,154 +286,127 @@ " \n", " \n", " \n", + " Unnamed: 0\n", " serialno\n", - " member_id\n", + " SPORDER\n", " puma00\n", " puma10\n", - " age\n", + " AGEP\n", " JWTR\n", - " relate\n", + " RELP\n", " SCH\n", - " edu\n", - " sex\n", + " SCHL\n", " ...\n", " ESR\n", " HISP\n", - " earning\n", - " race_id\n", + " PERNP\n", + " RAC1P\n", " hispanic\n", " person_age\n", " person_sex\n", " race\n", " cat_id\n", - " household_id\n", - " \n", - " \n", - " person_id\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", + " hh_id\n", " \n", " \n", " \n", " \n", " 0\n", - " 2012000184237\n", + " 0\n", + " 2012000016443\n", " 1\n", " -9\n", " 400\n", - " 43\n", - " 12.0\n", + " 45\n", + " 1.0\n", " 0\n", " 1.0\n", - " 16.0\n", - " 1\n", + " 19.0\n", " ...\n", " 1.0\n", " 1\n", - " 31000.0\n", + " 43200.0\n", " 4\n", " no\n", " 35 to 60\n", " male\n", " other\n", " 138262\n", - " 0\n", + " 112\n", " \n", " \n", " 1\n", - " 2012000184237\n", " 1\n", + " 2012000016443\n", + " 2\n", " -9\n", " 400\n", - " 43\n", - " 12.0\n", - " 0\n", - " 1.0\n", - " 16.0\n", + " 45\n", + " NaN\n", " 1\n", - " ...\n", " 1.0\n", + " 21.0\n", + " ...\n", + " 6.0\n", " 1\n", - " 31000.0\n", + " 0.0\n", " 4\n", " no\n", " 35 to 60\n", - " male\n", + " female\n", " other\n", - " 138262\n", - " 1\n", + " 138258\n", + " 112\n", " \n", " \n", " 2\n", - " 2012000200475\n", - " 1\n", + " 2\n", + " 2012000016443\n", + " 4\n", " -9\n", " 400\n", - " 39\n", - " 1.0\n", - " 0\n", - " 1.0\n", - " 19.0\n", - " 1\n", + " 11\n", + " NaN\n", + " 2\n", + " 2.0\n", + " 7.0\n", " ...\n", - " 1.0\n", + " NaN\n", " 1\n", - " 43300.0\n", - " 9\n", + " NaN\n", + " 4\n", " no\n", - " 35 to 60\n", - " male\n", + " 19 and under\n", + " female\n", " other\n", - " 138262\n", - " 8\n", + " 138242\n", + " 112\n", " \n", " \n", "\n", - "

3 rows × 21 columns

\n", + "

3 rows × 22 columns

\n", "" ], "text/plain": [ - " serialno member_id puma00 puma10 age JWTR relate SCH \\\n", - "person_id \n", - "0 2012000184237 1 -9 400 43 12.0 0 1.0 \n", - "1 2012000184237 1 -9 400 43 12.0 0 1.0 \n", - "2 2012000200475 1 -9 400 39 1.0 0 1.0 \n", + " Unnamed: 0 serialno SPORDER puma00 puma10 AGEP JWTR RELP SCH \\\n", + "0 0 2012000016443 1 -9 400 45 1.0 0 1.0 \n", + "1 1 2012000016443 2 -9 400 45 NaN 1 1.0 \n", + "2 2 2012000016443 4 -9 400 11 NaN 2 2.0 \n", "\n", - " edu sex ... ESR HISP earning race_id hispanic person_age \\\n", - "person_id ... \n", - "0 16.0 1 ... 1.0 1 31000.0 4 no 35 to 60 \n", - "1 16.0 1 ... 1.0 1 31000.0 4 no 35 to 60 \n", - "2 19.0 1 ... 1.0 1 43300.0 9 no 35 to 60 \n", + " SCHL ... ESR HISP PERNP RAC1P hispanic person_age person_sex \\\n", + "0 19.0 ... 1.0 1 43200.0 4 no 35 to 60 male \n", + "1 21.0 ... 6.0 1 0.0 4 no 35 to 60 female \n", + "2 7.0 ... NaN 1 NaN 4 no 19 and under female \n", "\n", - " person_sex race cat_id household_id \n", - "person_id \n", - "0 male other 138262 0 \n", - "1 male other 138262 1 \n", - "2 male other 138262 8 \n", + " race cat_id hh_id \n", + "0 other 138262 112 \n", + "1 other 138258 112 \n", + "2 other 138242 112 \n", "\n", - "[3 rows x 21 columns]" + "[3 rows x 22 columns]" ] }, - "execution_count": 6, + "execution_count": 5, "metadata": {}, "output_type": "execute_result" } @@ -505,7 +452,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 6, "metadata": {}, "outputs": [], "source": [ @@ -750,7 +697,7 @@ { "data": { "text/plain": [ - "" + "" ] }, "execution_count": 13, @@ -770,7 +717,7 @@ { "data": { "text/plain": [ - "" + "" ] }, "execution_count": 14, @@ -817,7 +764,7 @@ { "data": { "text/plain": [ - ">" + ">" ] }, "execution_count": 16, @@ -1357,12 +1304,12 @@ }, { "cell_type": "code", - "execution_count": 79, + "execution_count": 24, "metadata": {}, "outputs": [], "source": [ "# the None tract value correspond to all the tracts\n", - "h_acs_ = c.block_group_and_tract_query(block_group_columns=presence_of_children_columns,\n", + "h_acs = c.block_group_and_tract_query(block_group_columns=presence_of_children_columns,\n", " tract_columns=vehicle_columns, \n", " state='02', county='290',\n", " merge_columns=['tract', 'county', 'state'],\n", @@ -1373,7 +1320,7 @@ }, { "cell_type": "code", - "execution_count": 80, + "execution_count": 25, "metadata": {}, "outputs": [ { @@ -1466,7 +1413,7 @@ "1 214 71 30 5 13 " ] }, - "execution_count": 80, + "execution_count": 25, "metadata": {}, "output_type": "execute_result" } @@ -1491,7 +1438,7 @@ }, { "cell_type": "code", - "execution_count": 57, + "execution_count": 26, "metadata": {}, "outputs": [], "source": [ @@ -1500,7 +1447,7 @@ }, { "cell_type": "code", - "execution_count": 58, + "execution_count": 27, "metadata": {}, "outputs": [ { @@ -1509,7 +1456,7 @@ "" ] }, - "execution_count": 58, + "execution_count": 27, "metadata": {}, "output_type": "execute_result" } @@ -1527,7 +1474,7 @@ }, { "cell_type": "code", - "execution_count": 76, + "execution_count": 28, "metadata": {}, "outputs": [], "source": [ @@ -1542,7 +1489,7 @@ }, { "cell_type": "code", - "execution_count": 81, + "execution_count": 29, "metadata": {}, "outputs": [ { @@ -1697,7 +1644,7 @@ " 2 98 50 43 123 69" ] }, - "execution_count": 81, + "execution_count": 29, "metadata": {}, "output_type": "execute_result" } @@ -1715,7 +1662,7 @@ }, { "cell_type": "code", - "execution_count": 67, + "execution_count": 30, "metadata": {}, "outputs": [ { @@ -2108,7 +2055,7 @@ "[9 rows x 34 columns]" ] }, - "execution_count": 67, + "execution_count": 30, "metadata": {}, "output_type": "execute_result" } @@ -2141,16 +2088,16 @@ }, { "cell_type": "code", - "execution_count": 70, + "execution_count": 31, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - ">" + ">" ] }, - "execution_count": 70, + "execution_count": 31, "metadata": {}, "output_type": "execute_result" } @@ -2168,7 +2115,7 @@ }, { "cell_type": "code", - "execution_count": 108, + "execution_count": 32, "metadata": {}, "outputs": [ { @@ -2204,7 +2151,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "##### What we call slices?: the `PUMS` geographies " + "##### What we call slices?: the `PUMA` geographies " ] }, { @@ -2234,7 +2181,7 @@ }, { "cell_type": "code", - "execution_count": 123, + "execution_count": 33, "metadata": {}, "outputs": [], "source": [ @@ -2245,7 +2192,7 @@ }, { "cell_type": "code", - "execution_count": 125, + "execution_count": 34, "metadata": {}, "outputs": [ { @@ -2263,7 +2210,7 @@ }, { "cell_type": "code", - "execution_count": 126, + "execution_count": 35, "metadata": {}, "outputs": [ { @@ -2514,7 +2461,7 @@ "[3625 rows x 13 columns]" ] }, - "execution_count": 126, + "execution_count": 35, "metadata": {}, "output_type": "execute_result" } @@ -2534,12 +2481,12 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Joint distribution process represent ..." + "Joint distributions represents a total value for acs queried table. Since this last dataset contains aggregated data for tracts and block groups levels, and given that the PUMS are a representative sample of individual records - each serial number corresponds to a unique answer -, both tables will be used to build target values to be joined during the synthesis. " ] }, { "cell_type": "code", - "execution_count": 128, + "execution_count": 36, "metadata": {}, "outputs": [ { @@ -2548,7 +2495,7 @@ "" ] }, - "execution_count": 128, + "execution_count": 36, "metadata": {}, "output_type": "execute_result" } @@ -2566,7 +2513,7 @@ }, { "cell_type": "code", - "execution_count": 134, + "execution_count": 37, "metadata": {}, "outputs": [ { @@ -2642,7 +2589,7 @@ " yes 5" ] }, - "execution_count": 134, + "execution_count": 37, "metadata": {}, "output_type": "execute_result" } @@ -2660,7 +2607,7 @@ }, { "cell_type": "code", - "execution_count": 132, + "execution_count": 38, "metadata": {}, "outputs": [], "source": [ @@ -2680,7 +2627,7 @@ }, { "cell_type": "code", - "execution_count": 136, + "execution_count": 39, "metadata": {}, "outputs": [], "source": [ @@ -2697,12 +2644,12 @@ "source": [ "- **1. Categories dataframe**\n", "\n", - "This cointains the amount of cases (or frequencies) for each category combination within the PUMA geography that corresponds to all the tracts we passed to the `tract to puma` function:" + "This cointains the amount of cases (or frequencies) for each category combination within the PUMA geography. It is important to remark that this totals corresponds to all the tracts we passed to the `tract to puma` function. Given that PUMS returns individual answers for a bunch of variables, we can combine them based on acs subject table columns and get the totals of each combination for a group tracts. This will return a total value for a group of tracts (or PUMA). PUMAs are unique whitin a state." ] }, { "cell_type": "code", - "execution_count": 137, + "execution_count": 40, "metadata": {}, "outputs": [ { @@ -2786,7 +2733,7 @@ " yes 5 368" ] }, - "execution_count": 137, + "execution_count": 40, "metadata": {}, "output_type": "execute_result" } @@ -2806,7 +2753,7 @@ }, { "cell_type": "code", - "execution_count": 138, + "execution_count": 41, "metadata": {}, "outputs": [ { @@ -3093,7 +3040,7 @@ "[3625 rows x 16 columns]" ] }, - "execution_count": 138, + "execution_count": 41, "metadata": {}, "output_type": "execute_result" } @@ -3117,90 +3064,19 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## 2. Using `Starter` outputs " + "### 2.4. Marginals, the block group level" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "## Sinthesize all" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "DIAGRAM HERE: how Starter is used by the synthesized all function" - ] - }, - { - "cell_type": "code", - "execution_count": 148, - "metadata": {}, - "outputs": [], - "source": [ - "import logging\n", - "from collections import namedtuple" - ] - }, - { - "cell_type": "code", - "execution_count": 149, - "metadata": {}, - "outputs": [], - "source": [ - "logger = logging.getLogger(\"synthpop\")\n", - "FitQuality = namedtuple(\n", - " 'FitQuality',\n", - " ('people_chisq', 'people_p'))\n", - "BlockGroupID = namedtuple(\n", - " 'BlockGroupID', ('state', 'county', 'tract', 'block_group'))" - ] - }, - { - "cell_type": "code", - "execution_count": 151, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "__main__.BlockGroupID" - ] - }, - "execution_count": 151, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "BlockGroupID" - ] - }, - { - "cell_type": "code", - "execution_count": 152, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "__main__.FitQuality" - ] - }, - "execution_count": 152, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "FitQuality" + "Marginals are called from the `starter` object inside the `synthesize_all` function and returns..." ] }, { "cell_type": "code", - "execution_count": 162, + "execution_count": 128, "metadata": {}, "outputs": [ { @@ -3213,18 +3089,19 @@ "dtype: object" ] }, - "execution_count": 162, + "execution_count": 128, "metadata": {}, "output_type": "execute_result" } ], "source": [ + "#...for a group of available geographies inside a county/state pair\n", "list(starter.get_available_geography_ids())[0]" ] }, { "cell_type": "code", - "execution_count": 163, + "execution_count": 129, "metadata": {}, "outputs": [], "source": [ @@ -3233,7 +3110,7 @@ }, { "cell_type": "code", - "execution_count": 164, + "execution_count": 130, "metadata": {}, "outputs": [], "source": [ @@ -3245,12 +3122,12 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Marginals returns the total value of a given variable for the block group geography level:" + "***...the total value of a given variable for the block group geography levels:***" ] }, { "cell_type": "code", - "execution_count": 165, + "execution_count": 131, "metadata": {}, "outputs": [ { @@ -3294,175 +3171,303 @@ "Name: (02, 290, 000400, 2), dtype: int64" ] }, - "execution_count": 165, + "execution_count": 131, "metadata": {}, "output_type": "execute_result" } ], "source": [ + "# This is the marginal table we stored for the last census tract (400)\n", "h_marg" ] }, { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, + "cell_type": "markdown", "metadata": {}, - "outputs": [], "source": [ - "def from_fips_to_name(state, county):\n", - " lookup = pd.read_csv(\n", - " 'https://s3-us-west-1.amazonaws.com/synthpop-data2/national_county.txt', dtype='str')\n", - " data = lookup[(lookup['State ANSI'] == state) & (lookup['County ANSI'] == county)]\n", - " state_name = data['State'].unique()[0]\n", - " county_name = data['County Name'].unique()[0]\n", - " return state_name, county_name" + "For example, in our acs5 categorized table, in the block group 1 of the 000400 tract (we only stored the last geography since we ran a for loop) there are 82 households with childs and 46 with one car." ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 132, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
cat_namehh_carshh_children
cat_valuenoneonetwo or morenoyes
statecountytractblock group
022900001001119402612958
2214714825482
000200151738215157
28312013524398
00030011275847126108
2103473811476
3102463812167
00040019146399882
298504312369
\n", + "
" + ], + "text/plain": [ + "cat_name hh_cars hh_children \n", + "cat_value none one two or more no yes\n", + "state county tract block group \n", + "02 290 000100 1 119 40 26 129 58\n", + " 2 214 71 48 254 82\n", + " 000200 1 51 73 82 151 57\n", + " 2 83 120 135 243 98\n", + " 000300 1 127 58 47 126 108\n", + " 2 103 47 38 114 76\n", + " 3 102 46 38 121 67\n", + " 000400 1 91 46 39 98 82\n", + " 2 98 50 43 123 69" + ] + }, + "execution_count": 132, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "from_fips_to_name('02', '290')" + "# can check these totals in our acs subject table...\n", + "h_acs_cat" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 134, "metadata": {}, "outputs": [], "source": [ - "def key():\n", - " return os.environ['CENSUS']" + "# store the block group 1 of the 000400 census tract\n", + "block_gp_1 = h_acs_cat.loc[tuple(list(starter.get_available_geography_ids())[7])]" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 135, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "cat_name cat_value \n", + "hh_cars none 91\n", + " one 46\n", + " two or more 39\n", + "hh_children no 98\n", + " yes 82\n", + "Name: (02, 290, 000400, 1), dtype: int64" + ] + }, + "execution_count": 135, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "starter = Starter(key(), 'AK', 'Yukon-Koyukuk Census Area', acsyear=2013)" + "block_gp_1" ] }, { - "cell_type": "code", - "execution_count": null, + "cell_type": "markdown", "metadata": {}, - "outputs": [], "source": [ - "starter" + "## 3. Sinthesize all: using `Starter` outputs " ] }, { - "cell_type": "code", - "execution_count": null, + "cell_type": "markdown", "metadata": {}, - "outputs": [], "source": [ - "geog = starter.c.try_fips_lookup('AK', 'Yukon-Koyukuk Census Area')\n", - "ind = pd.Series([geog[0]], index=[\"state\"])" + "DIAGRAM HERE: how Starter is used by the synthesized all function" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 136, "metadata": {}, "outputs": [], "source": [ - "geog" + "from synthpop.ipf.ipf import calculate_constraints" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 137, "metadata": {}, "outputs": [], "source": [ - "ind" + "h_constraint, _ = calculate_constraints(block_gp_1, jd_households.frequency)" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 138, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "hh_cars hh_children\n", + "none no 46.529753\n", + " yes 46.538428\n", + "one no 27.835805\n", + " yes 19.209650\n", + "two or more no 23.634442\n", + " yes 16.251921\n", + "dtype: float64" + ] + }, + "execution_count": 138, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "hh_target = starter.get_household_marginal_for_geography(ind)\n", - "p_target = starter.get_person_marginal_for_geography(ind)" + "h_constraint" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 139, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "4" + ] + }, + "execution_count": 139, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "hh_target.columns" + "_" ] }, { @@ -3470,29 +3475,21 @@ "execution_count": null, "metadata": {}, "outputs": [], - "source": [ - "hh_target.columns.names" - ] + "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], - "source": [ - "pd.set_option('display.max_rows', 500)\n", - "pd.set_option('display.max_columns', 500)\n", - "pd.set_option('display.width', 1000)" - ] + "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], - "source": [ - "hh_target.iloc[:,0:5]" - ] + "source": [] }, { "cell_type": "code", From b99c45e8755f29cfc79162be29f35c043cb745af Mon Sep 17 00:00:00 2001 From: PyMap Date: Tue, 28 Jul 2020 10:26:40 -0300 Subject: [PATCH 10/12] ipu --- demos/Synthesis workflow.ipynb | 2232 ++++++++++++++++++++++++++++++-- 1 file changed, 2120 insertions(+), 112 deletions(-) diff --git a/demos/Synthesis workflow.ipynb b/demos/Synthesis workflow.ipynb index 32b7013..60ff2b5 100644 --- a/demos/Synthesis workflow.ipynb +++ b/demos/Synthesis workflow.ipynb @@ -6,21 +6,13 @@ "metadata": {}, "outputs": [], "source": [ - "from fpdf import FPDF\n", - "import seaborn as sns\n", - "import matplotlib.pyplot as plt\n", "import pandas as pd\n", "import numpy as np\n", "import os\n", "import sys\n", - "import argparse\n", "\n", "from synthpop.recipes.starter2 import Starter\n", - "from synthpop.census_helpers import Census\n", - "import warnings\n", - "warnings.filterwarnings('ignore')\n", - "\n", - "sns.set()" + "from synthpop.census_helpers import Census" ] }, { @@ -67,26 +59,27 @@ "name": "stdout", "output_type": "stream", "text": [ - "02_290.pdf \u001b[0m\u001b[01;32mhh_02_195_2013.csv\u001b[0m* \u001b[01;32mp_02_110_2013.csv\u001b[0m*\r\n", - "\u001b[01;32mhh_02_013_2013.csv\u001b[0m* \u001b[01;32mhh_02_198_2013.csv\u001b[0m* \u001b[01;32mp_02_122_2013.csv\u001b[0m*\r\n", - "\u001b[01;32mhh_02_016_2013.csv\u001b[0m* \u001b[01;32mhh_02_220_2013.csv\u001b[0m* \u001b[01;32mp_02_130_2013.csv\u001b[0m*\r\n", - "\u001b[01;32mhh_02_020_2013.csv\u001b[0m* \u001b[01;32mhh_02_230_2013.csv\u001b[0m* \u001b[01;32mp_02_150_2013.csv\u001b[0m*\r\n", - "\u001b[01;32mhh_02_050_2013.csv\u001b[0m* \u001b[01;32mhh_02_240_2013.csv\u001b[0m* \u001b[01;32mp_02_164_2013.csv\u001b[0m*\r\n", - "\u001b[01;32mhh_02_060_2013.csv\u001b[0m* \u001b[01;32mhh_02_261_2013.csv\u001b[0m* \u001b[01;32mp_02_170_2013.csv\u001b[0m*\r\n", - "\u001b[01;32mhh_02_068_2013.csv\u001b[0m* \u001b[01;32mhh_02_270_2013.csv\u001b[0m* \u001b[01;32mp_02_180_2013.csv\u001b[0m*\r\n", - "\u001b[01;32mhh_02_070_2013.csv\u001b[0m* \u001b[01;32mhh_02_275_2013.csv\u001b[0m* \u001b[01;32mp_02_185_2013.csv\u001b[0m*\r\n", - "\u001b[01;32mhh_02_090_2013.csv\u001b[0m* \u001b[01;32mhh_02_282_2013.csv\u001b[0m* \u001b[01;32mp_02_188_2013.csv\u001b[0m*\r\n", - "\u001b[01;32mhh_02_100_2013.csv\u001b[0m* \u001b[01;32mhh_02_290_2013.csv\u001b[0m* \u001b[01;32mp_02_195_2013.csv\u001b[0m*\r\n", - "\u001b[01;32mhh_02_105_2013.csv\u001b[0m* \u001b[01;32mp_02_013_2013.csv\u001b[0m* \u001b[01;32mp_02_198_2013.csv\u001b[0m*\r\n", - "\u001b[01;32mhh_02_110_2013.csv\u001b[0m* \u001b[01;32mp_02_016_2013.csv\u001b[0m* \u001b[01;32mp_02_220_2013.csv\u001b[0m*\r\n", - "\u001b[01;32mhh_02_122_2013.csv\u001b[0m* \u001b[01;32mp_02_020_2013.csv\u001b[0m* \u001b[01;32mp_02_230_2013.csv\u001b[0m*\r\n", - "\u001b[01;32mhh_02_130_2013.csv\u001b[0m* \u001b[01;32mp_02_050_2013.csv\u001b[0m* \u001b[01;32mp_02_240_2013.csv\u001b[0m*\r\n", - "\u001b[01;32mhh_02_150_2013.csv\u001b[0m* \u001b[01;32mp_02_060_2013.csv\u001b[0m* \u001b[01;32mp_02_261_2013.csv\u001b[0m*\r\n", - "\u001b[01;32mhh_02_164_2013.csv\u001b[0m* \u001b[01;32mp_02_068_2013.csv\u001b[0m* \u001b[01;32mp_02_270_2013.csv\u001b[0m*\r\n", - "\u001b[01;32mhh_02_170_2013.csv\u001b[0m* \u001b[01;32mp_02_070_2013.csv\u001b[0m* \u001b[01;32mp_02_275_2013.csv\u001b[0m*\r\n", - "\u001b[01;32mhh_02_180_2013.csv\u001b[0m* \u001b[01;32mp_02_090_2013.csv\u001b[0m* \u001b[01;32mp_02_282_2013.csv\u001b[0m*\r\n", - "\u001b[01;32mhh_02_185_2013.csv\u001b[0m* \u001b[01;32mp_02_100_2013.csv\u001b[0m* \u001b[01;32mp_02_290_2013.csv\u001b[0m*\r\n", - "\u001b[01;32mhh_02_188_2013.csv\u001b[0m* \u001b[01;32mp_02_105_2013.csv\u001b[0m*\r\n" + "02_198.pdf \u001b[0m\u001b[01;32mhh_02_188_2013.csv\u001b[0m* \u001b[01;32mp_02_110_2013.csv\u001b[0m*\r\n", + "02_261.pdf \u001b[01;32mhh_02_195_2013.csv\u001b[0m* \u001b[01;32mp_02_122_2013.csv\u001b[0m*\r\n", + "02_290.pdf \u001b[01;32mhh_02_198_2013.csv\u001b[0m* \u001b[01;32mp_02_130_2013.csv\u001b[0m*\r\n", + "\u001b[01;32mhh_02_013_2013.csv\u001b[0m* \u001b[01;32mhh_02_220_2013.csv\u001b[0m* \u001b[01;32mp_02_150_2013.csv\u001b[0m*\r\n", + "\u001b[01;32mhh_02_016_2013.csv\u001b[0m* \u001b[01;32mhh_02_230_2013.csv\u001b[0m* \u001b[01;32mp_02_164_2013.csv\u001b[0m*\r\n", + "\u001b[01;32mhh_02_020_2013.csv\u001b[0m* \u001b[01;32mhh_02_240_2013.csv\u001b[0m* \u001b[01;32mp_02_170_2013.csv\u001b[0m*\r\n", + "\u001b[01;32mhh_02_050_2013.csv\u001b[0m* \u001b[01;32mhh_02_261_2013.csv\u001b[0m* \u001b[01;32mp_02_180_2013.csv\u001b[0m*\r\n", + "\u001b[01;32mhh_02_060_2013.csv\u001b[0m* \u001b[01;32mhh_02_270_2013.csv\u001b[0m* \u001b[01;32mp_02_185_2013.csv\u001b[0m*\r\n", + "\u001b[01;32mhh_02_068_2013.csv\u001b[0m* \u001b[01;32mhh_02_275_2013.csv\u001b[0m* \u001b[01;32mp_02_188_2013.csv\u001b[0m*\r\n", + "\u001b[01;32mhh_02_070_2013.csv\u001b[0m* \u001b[01;32mhh_02_282_2013.csv\u001b[0m* \u001b[01;32mp_02_195_2013.csv\u001b[0m*\r\n", + "\u001b[01;32mhh_02_090_2013.csv\u001b[0m* \u001b[01;32mhh_02_290_2013.csv\u001b[0m* \u001b[01;32mp_02_198_2013.csv\u001b[0m*\r\n", + "\u001b[01;32mhh_02_100_2013.csv\u001b[0m* \u001b[01;32mp_02_013_2013.csv\u001b[0m* \u001b[01;32mp_02_220_2013.csv\u001b[0m*\r\n", + "\u001b[01;32mhh_02_105_2013.csv\u001b[0m* \u001b[01;32mp_02_016_2013.csv\u001b[0m* \u001b[01;32mp_02_230_2013.csv\u001b[0m*\r\n", + "\u001b[01;32mhh_02_110_2013.csv\u001b[0m* \u001b[01;32mp_02_020_2013.csv\u001b[0m* \u001b[01;32mp_02_240_2013.csv\u001b[0m*\r\n", + "\u001b[01;32mhh_02_122_2013.csv\u001b[0m* \u001b[01;32mp_02_050_2013.csv\u001b[0m* \u001b[01;32mp_02_261_2013.csv\u001b[0m*\r\n", + "\u001b[01;32mhh_02_130_2013.csv\u001b[0m* \u001b[01;32mp_02_060_2013.csv\u001b[0m* \u001b[01;32mp_02_270_2013.csv\u001b[0m*\r\n", + "\u001b[01;32mhh_02_150_2013.csv\u001b[0m* \u001b[01;32mp_02_068_2013.csv\u001b[0m* \u001b[01;32mp_02_275_2013.csv\u001b[0m*\r\n", + "\u001b[01;32mhh_02_164_2013.csv\u001b[0m* \u001b[01;32mp_02_070_2013.csv\u001b[0m* \u001b[01;32mp_02_282_2013.csv\u001b[0m*\r\n", + "\u001b[01;32mhh_02_170_2013.csv\u001b[0m* \u001b[01;32mp_02_090_2013.csv\u001b[0m* \u001b[01;32mp_02_290_2013.csv\u001b[0m*\r\n", + "\u001b[01;32mhh_02_180_2013.csv\u001b[0m* \u001b[01;32mp_02_100_2013.csv\u001b[0m*\r\n", + "\u001b[01;32mhh_02_185_2013.csv\u001b[0m* \u001b[01;32mp_02_105_2013.csv\u001b[0m*\r\n" ] } ], @@ -468,7 +461,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 7, "metadata": {}, "outputs": [], "source": [ @@ -478,7 +471,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 8, "metadata": {}, "outputs": [ { @@ -503,7 +496,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 9, "metadata": {}, "outputs": [ { @@ -512,7 +505,7 @@ "('02', '290')" ] }, - "execution_count": 10, + "execution_count": 9, "metadata": {}, "output_type": "execute_result" } @@ -545,7 +538,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 10, "metadata": {}, "outputs": [ { @@ -670,7 +663,7 @@ "[2 rows x 127 columns]" ] }, - "execution_count": 11, + "execution_count": 10, "metadata": {}, "output_type": "execute_result" } @@ -681,7 +674,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 11, "metadata": {}, "outputs": [], "source": [ @@ -691,16 +684,16 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "" + "" ] }, - "execution_count": 13, + "execution_count": 12, "metadata": {}, "output_type": "execute_result" } @@ -711,16 +704,16 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "" + "" ] }, - "execution_count": 14, + "execution_count": 13, "metadata": {}, "output_type": "execute_result" } @@ -731,7 +724,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 14, "metadata": {}, "outputs": [ { @@ -758,16 +751,16 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - ">" + ">" ] }, - "execution_count": 16, + "execution_count": 15, "metadata": {}, "output_type": "execute_result" } @@ -788,7 +781,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 16, "metadata": {}, "outputs": [ { @@ -813,7 +806,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 17, "metadata": {}, "outputs": [], "source": [ @@ -828,7 +821,7 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 18, "metadata": {}, "outputs": [], "source": [ @@ -839,7 +832,7 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 19, "metadata": {}, "outputs": [ { @@ -931,7 +924,7 @@ "3 151.0 221.0 02 290 000400 " ] }, - "execution_count": 20, + "execution_count": 19, "metadata": {}, "output_type": "execute_result" } @@ -942,7 +935,7 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 20, "metadata": {}, "outputs": [], "source": [ @@ -953,7 +946,7 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 21, "metadata": {}, "outputs": [ { @@ -1115,7 +1108,7 @@ "8 69.0 123.0 02 290 000400 2 " ] }, - "execution_count": 22, + "execution_count": 21, "metadata": {}, "output_type": "execute_result" } @@ -1133,7 +1126,7 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 22, "metadata": {}, "outputs": [ { @@ -1285,7 +1278,7 @@ "8 98 50 35 5 3 " ] }, - "execution_count": 23, + "execution_count": 22, "metadata": {}, "output_type": "execute_result" } @@ -1304,7 +1297,7 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 23, "metadata": {}, "outputs": [], "source": [ @@ -1320,7 +1313,7 @@ }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 24, "metadata": {}, "outputs": [ { @@ -1413,7 +1406,7 @@ "1 214 71 30 5 13 " ] }, - "execution_count": 25, + "execution_count": 24, "metadata": {}, "output_type": "execute_result" } @@ -1438,7 +1431,7 @@ }, { "cell_type": "code", - "execution_count": 26, + "execution_count": 25, "metadata": {}, "outputs": [], "source": [ @@ -1447,7 +1440,7 @@ }, { "cell_type": "code", - "execution_count": 27, + "execution_count": 26, "metadata": {}, "outputs": [ { @@ -1456,7 +1449,7 @@ "" ] }, - "execution_count": 27, + "execution_count": 26, "metadata": {}, "output_type": "execute_result" } @@ -1474,7 +1467,7 @@ }, { "cell_type": "code", - "execution_count": 28, + "execution_count": 27, "metadata": {}, "outputs": [], "source": [ @@ -1489,7 +1482,7 @@ }, { "cell_type": "code", - "execution_count": 29, + "execution_count": 28, "metadata": {}, "outputs": [ { @@ -1644,7 +1637,7 @@ " 2 98 50 43 123 69" ] }, - "execution_count": 29, + "execution_count": 28, "metadata": {}, "output_type": "execute_result" } @@ -1662,7 +1655,7 @@ }, { "cell_type": "code", - "execution_count": 30, + "execution_count": 29, "metadata": {}, "outputs": [ { @@ -2055,7 +2048,7 @@ "[9 rows x 34 columns]" ] }, - "execution_count": 30, + "execution_count": 29, "metadata": {}, "output_type": "execute_result" } @@ -2088,16 +2081,16 @@ }, { "cell_type": "code", - "execution_count": 31, + "execution_count": 30, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - ">" + ">" ] }, - "execution_count": 31, + "execution_count": 30, "metadata": {}, "output_type": "execute_result" } @@ -2115,7 +2108,7 @@ }, { "cell_type": "code", - "execution_count": 32, + "execution_count": 31, "metadata": {}, "outputs": [ { @@ -2181,7 +2174,7 @@ }, { "cell_type": "code", - "execution_count": 33, + "execution_count": 32, "metadata": {}, "outputs": [], "source": [ @@ -2192,7 +2185,7 @@ }, { "cell_type": "code", - "execution_count": 34, + "execution_count": 33, "metadata": {}, "outputs": [ { @@ -2210,7 +2203,7 @@ }, { "cell_type": "code", - "execution_count": 35, + "execution_count": 34, "metadata": {}, "outputs": [ { @@ -2461,7 +2454,7 @@ "[3625 rows x 13 columns]" ] }, - "execution_count": 35, + "execution_count": 34, "metadata": {}, "output_type": "execute_result" } @@ -2486,7 +2479,7 @@ }, { "cell_type": "code", - "execution_count": 36, + "execution_count": 35, "metadata": {}, "outputs": [ { @@ -2495,7 +2488,7 @@ "" ] }, - "execution_count": 36, + "execution_count": 35, "metadata": {}, "output_type": "execute_result" } @@ -2513,7 +2506,7 @@ }, { "cell_type": "code", - "execution_count": 37, + "execution_count": 36, "metadata": {}, "outputs": [ { @@ -2589,7 +2582,7 @@ " yes 5" ] }, - "execution_count": 37, + "execution_count": 36, "metadata": {}, "output_type": "execute_result" } @@ -2607,7 +2600,7 @@ }, { "cell_type": "code", - "execution_count": 38, + "execution_count": 37, "metadata": {}, "outputs": [], "source": [ @@ -2627,7 +2620,7 @@ }, { "cell_type": "code", - "execution_count": 39, + "execution_count": 38, "metadata": {}, "outputs": [], "source": [ @@ -2649,7 +2642,7 @@ }, { "cell_type": "code", - "execution_count": 40, + "execution_count": 39, "metadata": {}, "outputs": [ { @@ -2733,7 +2726,7 @@ " yes 5 368" ] }, - "execution_count": 40, + "execution_count": 39, "metadata": {}, "output_type": "execute_result" } @@ -2753,7 +2746,7 @@ }, { "cell_type": "code", - "execution_count": 41, + "execution_count": 40, "metadata": {}, "outputs": [ { @@ -3040,7 +3033,7 @@ "[3625 rows x 16 columns]" ] }, - "execution_count": 41, + "execution_count": 40, "metadata": {}, "output_type": "execute_result" } @@ -3076,7 +3069,7 @@ }, { "cell_type": "code", - "execution_count": 128, + "execution_count": 41, "metadata": {}, "outputs": [ { @@ -3089,7 +3082,7 @@ "dtype: object" ] }, - "execution_count": 128, + "execution_count": 41, "metadata": {}, "output_type": "execute_result" } @@ -3101,7 +3094,7 @@ }, { "cell_type": "code", - "execution_count": 129, + "execution_count": 42, "metadata": {}, "outputs": [], "source": [ @@ -3110,7 +3103,7 @@ }, { "cell_type": "code", - "execution_count": 130, + "execution_count": 43, "metadata": {}, "outputs": [], "source": [ @@ -3127,7 +3120,7 @@ }, { "cell_type": "code", - "execution_count": 131, + "execution_count": 44, "metadata": {}, "outputs": [ { @@ -3171,7 +3164,7 @@ "Name: (02, 290, 000400, 2), dtype: int64" ] }, - "execution_count": 131, + "execution_count": 44, "metadata": {}, "output_type": "execute_result" } @@ -3190,7 +3183,7 @@ }, { "cell_type": "code", - "execution_count": 132, + "execution_count": 45, "metadata": {}, "outputs": [ { @@ -3345,7 +3338,7 @@ " 2 98 50 43 123 69" ] }, - "execution_count": 132, + "execution_count": 45, "metadata": {}, "output_type": "execute_result" } @@ -3357,17 +3350,17 @@ }, { "cell_type": "code", - "execution_count": 134, + "execution_count": 46, "metadata": {}, "outputs": [], "source": [ - "# store the block group 1 of the 000400 census tract\n", - "block_gp_1 = h_acs_cat.loc[tuple(list(starter.get_available_geography_ids())[7])]" + "# store the marginal values from the block group 1 of the 000400 census tract\n", + "hh_marginals_tract_400_block_gp_1 = h_acs_cat.loc[tuple(list(starter.get_available_geography_ids())[7])]" ] }, { "cell_type": "code", - "execution_count": 135, + "execution_count": 47, "metadata": {}, "outputs": [ { @@ -3382,13 +3375,13 @@ "Name: (02, 290, 000400, 1), dtype: int64" ] }, - "execution_count": 135, + "execution_count": 47, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "block_gp_1" + "hh_marginals_tract_400_block_gp_1" ] }, { @@ -3402,12 +3395,19 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "DIAGRAM HERE: how Starter is used by the synthesized all function" + "### 3.1 The iterative proportional fitting (IPF) procedure " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "![constraints](img/constraints.png)" ] }, { "cell_type": "code", - "execution_count": 136, + "execution_count": 48, "metadata": {}, "outputs": [], "source": [ @@ -3416,16 +3416,16 @@ }, { "cell_type": "code", - "execution_count": 137, + "execution_count": 49, "metadata": {}, "outputs": [], "source": [ - "h_constraint, _ = calculate_constraints(block_gp_1, jd_households.frequency)" + "h_constraint, _ = calculate_constraints(hh_marginals_tract_400_block_gp_1, jd_households.frequency)" ] }, { "cell_type": "code", - "execution_count": 138, + "execution_count": 50, "metadata": {}, "outputs": [ { @@ -3441,18 +3441,19 @@ "dtype: float64" ] }, - "execution_count": 138, + "execution_count": 50, "metadata": {}, "output_type": "execute_result" } ], "source": [ + "# this is our contraints table\n", "h_constraint" ] }, { "cell_type": "code", - "execution_count": 139, + "execution_count": 51, "metadata": {}, "outputs": [ { @@ -3461,28 +3462,2035 @@ "4" ] }, - "execution_count": 139, + "execution_count": 51, "metadata": {}, "output_type": "execute_result" } ], "source": [ + "# this is the number of iterations performed to achieve the constraint values\n", "_" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In the block group 1 of the census tract 400 we used to have 91 households with no cars, 46 with one car and 39 with two or more:" + ] + }, { "cell_type": "code", - "execution_count": null, + "execution_count": 52, "metadata": {}, "outputs": [], - "source": [] + "source": [ + "bg_targets = hh_marginals_tract_400_block_gp_1[:3]" + ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 53, "metadata": {}, - "outputs": [], - "source": [] + "outputs": [ + { + "data": { + "text/plain": [ + "cat_name cat_value \n", + "hh_cars none 91\n", + " one 46\n", + " two or more 39\n", + "Name: (02, 290, 000400, 1), dtype: int64" + ] + }, + "execution_count": 53, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "bg_targets" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "At the same time, our `joint_distributions` table gave us the total of that variable for the entire PUMA (in this case, `843 households with no children + 919 households with one children = 1762 households with no cars`:" + ] + }, + { + "cell_type": "code", + "execution_count": 54, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
cat_idfrequency
hh_carshh_children
noneno0843
yes1919
\n", + "
" + ], + "text/plain": [ + " cat_id frequency\n", + "hh_cars hh_children \n", + "none no 0 843\n", + " yes 1 919" + ] + }, + "execution_count": 54, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "jd_households[:2]" + ] + }, + { + "cell_type": "code", + "execution_count": 55, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "1762" + ] + }, + "execution_count": 55, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "jd_households['frequency'][:2].sum()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "With this information, we will build new target values for each category total within the block group by multiplying the target and the proportion that this target represents in the entire PUMA - remember here, that our joint distribution table gets this total by combining different variables. In our case number of cars and children -\n", + "\n", + "`new_target = current_target * (proportion of the current target)`" + ] + }, + { + "cell_type": "code", + "execution_count": 56, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Block group target value: 91\n", + "Total value of the combined category is: 1762\n", + "Proportion of each category in the combined variables total: 0.051645856980703744\n", + "New Block group target value: 4.69977298524404\n", + "*********************************************************************************\n", + "Block group target value: 46\n", + "Total value of the combined category is: 1004\n", + "Proportion of each category in the combined variables total: 0.045816733067729085\n", + "New Block group target value: 2.1075697211155378\n", + "*********************************************************************************\n", + "Block group target value: 39\n", + "Total value of the combined category is: 859\n", + "Proportion of each category in the combined variables total: 0.04540162980209546\n", + "New Block group target value: 1.7706635622817228\n", + "*********************************************************************************\n" + ] + } + ], + "source": [ + "sub_category_idx_0 = 0\n", + "sub_category_idx_1 = 2\n", + "\n", + "for target in range(len(bg_targets)):\n", + " total_cat = jd_households.frequency[sub_category_idx_0:sub_category_idx_1].sum()\n", + " sub_category_idx_0 += 2\n", + " sub_category_idx_1 += 2\n", + " print('Block group target value: %s'%str(bg_targets[target]))\n", + " print('Total value of the combined category is: %s'%str(total_cat))\n", + " print('Proportion of each category in the combined variables total: %s'%str(bg_targets[target] / total_cat))\n", + " print('New Block group target value: %s'%str(bg_targets[target]*(bg_targets[target] / total_cat)))\n", + " print('*********************************************************************************')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "These new values that were built based on the proportion that each block group represents in the PUMA (for every category value) will be used to update our joint distributions table: " + ] + }, + { + "cell_type": "code", + "execution_count": 57, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[ 0, 843],\n", + " [ 1, 919],\n", + " [ 2, 573],\n", + " [ 3, 431],\n", + " [ 4, 491],\n", + " [ 5, 368]])" + ] + }, + "execution_count": 57, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "jd_households.values" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "...the totals we had for each `category combination`: 0; 1; 2; 3; 4 & 5 will be replaced using that proportion. This way we will define a new maximum value for every category within the block group." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Imagine we have a constraints table with categories from 0 to 2 (has no car and no children, has no car but children and has one car and no children) as we shown in the example above. We will need to:" + ] + }, + { + "cell_type": "code", + "execution_count": 58, + "metadata": {}, + "outputs": [], + "source": [ + "current_constraints = jd_households[:3].values.copy()" + ] + }, + { + "cell_type": "code", + "execution_count": 59, + "metadata": {}, + "outputs": [], + "source": [ + "# 1. define new targets based on proportions\n", + "new_targets = [4.69977298524404, 2.1075697211155378, 1.7706635622817228]\n", + "\n", + "next_constraints = current_constraints.astype(float)" + ] + }, + { + "cell_type": "code", + "execution_count": 60, + "metadata": {}, + "outputs": [], + "source": [ + "# 2. update the constraints table\n", + "fre = -1\n", + "for t in new_targets:\n", + " fre +=1 \n", + " next_constraints[fre][1] = t" + ] + }, + { + "cell_type": "code", + "execution_count": 61, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[0. , 4.69977299],\n", + " [1. , 2.10756972],\n", + " [2. , 1.77066356]])" + ] + }, + "execution_count": 61, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "next_constraints" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "These values will be updated inside an iterative process, where previous and next constraints will be evaluated under a maximum of `tolerance`: " + ] + }, + { + "cell_type": "code", + "execution_count": 62, + "metadata": {}, + "outputs": [], + "source": [ + "tolerance = 1e-3" + ] + }, + { + "cell_type": "code", + "execution_count": 63, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "2338.0" + ] + }, + "execution_count": 63, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.abs(current_constraints, next_constraints).sum()" + ] + }, + { + "cell_type": "code", + "execution_count": 64, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Recalculate constraints table\n" + ] + } + ], + "source": [ + "if np.abs(current_constraints, next_constraints).sum()>tolerance:\n", + " print('Recalculate constraints table')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This way, the iteration will continue until reaching a group of new target values under the tolerance defined before. The man result of this process will be..." + ] + }, + { + "cell_type": "code", + "execution_count": 65, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "cat_name cat_value \n", + "hh_cars none 91\n", + " one 46\n", + " two or more 39\n", + "hh_children no 98\n", + " yes 82\n", + "Name: (02, 290, 000400, 1), dtype: int64" + ] + }, + "execution_count": 65, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# ... our marginals table with total values for the block group\n", + "hh_marginals_tract_400_block_gp_1" + ] + }, + { + "cell_type": "code", + "execution_count": 66, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "hh_cars hh_children\n", + "none no 46.529753\n", + " yes 46.538428\n", + "one no 27.835805\n", + " yes 19.209650\n", + "two or more no 23.634442\n", + " yes 16.251921\n", + "dtype: float64" + ] + }, + "execution_count": 66, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# updated with new totals.\n", + "h_constraint" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Consuming the Census API we built a dataset with, for example, 91 aggregated cases for households with no car. Building the constraints table, we used PUMA geographies to determine the proportion that these 91 cases represents in a more dissaggregated level. With this estimation we determine that instead of 91, the block group 1 of the census tract 00400 from the Yukon-Koyukuk county in the Alaska state has 46.5 households with no car. " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 3.2. The iterative proportional updating (IPU) procedure " + ] + }, + { + "cell_type": "code", + "execution_count": 106, + "metadata": {}, + "outputs": [], + "source": [ + "from synthpop.ipu.ipu import household_weights" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 67, + "metadata": {}, + "outputs": [], + "source": [ + "h_constraint.index = jd_households.cat_id" + ] + }, + { + "cell_type": "code", + "execution_count": 68, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "cat_id\n", + "0 46.529753\n", + "1 46.538428\n", + "2 27.835805\n", + "3 19.209650\n", + "4 23.634442\n", + "5 16.251921\n", + "dtype: float64" + ] + }, + "execution_count": 68, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "h_constraint" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Besides the `categories dataframe` - our joint distributions table- we mentioned in `2.3`, there is a `sample dataframe` which is the public user microdata sample - our pums." + ] + }, + { + "cell_type": "code", + "execution_count": 69, + "metadata": {}, + "outputs": [], + "source": [ + "households_sample_df = h_pums.copy()" + ] + }, + { + "cell_type": "code", + "execution_count": 70, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
serialnoRTpuma00puma10NPTYPEBLDTENVEHHINCPMVR18R65hh_carshh_childrencat_id
02012000000643H-9400212.03.00.033360.01.00.00.0noneno0
22012000001889H-9400412.02.00.089420.07.00.02.0noneno0
32012000003083H-9400112.02.00.020800.07.00.00.0noneno0
152012000017291H-9400412.02.00.054800.05.00.00.0noneno0
312012000041419H-9400212.02.00.033300.07.00.01.0noneno0
\n", + "
" + ], + "text/plain": [ + " serialno RT puma00 puma10 NP TYPE BLD TEN VEH HINCP MV \\\n", + "0 2012000000643 H -9 400 2 1 2.0 3.0 0.0 33360.0 1.0 \n", + "2 2012000001889 H -9 400 4 1 2.0 2.0 0.0 89420.0 7.0 \n", + "3 2012000003083 H -9 400 1 1 2.0 2.0 0.0 20800.0 7.0 \n", + "15 2012000017291 H -9 400 4 1 2.0 2.0 0.0 54800.0 5.0 \n", + "31 2012000041419 H -9 400 2 1 2.0 2.0 0.0 33300.0 7.0 \n", + "\n", + " R18 R65 hh_cars hh_children cat_id \n", + "0 0.0 0.0 none no 0 \n", + "2 0.0 2.0 none no 0 \n", + "3 0.0 0.0 none no 0 \n", + "15 0.0 0.0 none no 0 \n", + "31 0.0 1.0 none no 0 " + ] + }, + "execution_count": 70, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "households_sample_df.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 71, + "metadata": {}, + "outputs": [], + "source": [ + "households_sample_df.index.name = \"hh_id\"" + ] + }, + { + "cell_type": "code", + "execution_count": 72, + "metadata": {}, + "outputs": [], + "source": [ + "households_sample_df = households_sample_df.reset_index().set_index(\"serialno\")" + ] + }, + { + "cell_type": "code", + "execution_count": 73, + "metadata": {}, + "outputs": [], + "source": [ + "h_freq_table = cat._frequency_table(households_sample_df, jd_households.cat_id)" + ] + }, + { + "cell_type": "code", + "execution_count": 74, + "metadata": {}, + "outputs": [], + "source": [ + "h_freq_table = h_freq_table.sort_index(axis=1)" + ] + }, + { + "cell_type": "code", + "execution_count": 75, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
cat_id012345
hh_id
01.00.00.00.00.00.0
21.00.00.00.00.00.0
31.00.00.00.00.00.0
40.01.00.00.00.00.0
50.00.00.01.00.00.0
\n", + "
" + ], + "text/plain": [ + "cat_id 0 1 2 3 4 5\n", + "hh_id \n", + "0 1.0 0.0 0.0 0.0 0.0 0.0\n", + "2 1.0 0.0 0.0 0.0 0.0 0.0\n", + "3 1.0 0.0 0.0 0.0 0.0 0.0\n", + "4 0.0 1.0 0.0 0.0 0.0 0.0\n", + "5 0.0 0.0 0.0 1.0 0.0 0.0" + ] + }, + "execution_count": 75, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "h_freq_table.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 107, + "metadata": {}, + "outputs": [], + "source": [ + "best_weights, fit_quality, iterations = household_weights(h_freq_table,\n", + " None,\n", + " h_constraint,\n", + " None)" + ] + }, + { + "cell_type": "code", + "execution_count": 108, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "hh_id\n", + "0 0.055195\n", + "2 0.055195\n", + "3 0.055195\n", + "4 0.050640\n", + "5 0.044570\n", + " ... \n", + "5857 0.044570\n", + "5858 0.050640\n", + "5862 0.048135\n", + "5865 0.055195\n", + "5868 0.044570\n", + "Length: 3625, dtype: float64" + ] + }, + "execution_count": 108, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "best_weights" + ] + }, + { + "cell_type": "code", + "execution_count": 109, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "1.636802750002612e-16" + ] + }, + "execution_count": 109, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "fit_quality" + ] + }, + { + "cell_type": "code", + "execution_count": 110, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "2" + ] + }, + "execution_count": 110, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "iterations" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 111, + "metadata": {}, + "outputs": [], + "source": [ + "weights = np.ones(len(h_freq_table), dtype='float')\n", + "best_weights = weights.copy()" + ] + }, + { + "cell_type": "code", + "execution_count": 113, + "metadata": {}, + "outputs": [], + "source": [ + "from synthpop.ipu.ipu import _FrequencyAndConstraints" + ] + }, + { + "cell_type": "code", + "execution_count": 116, + "metadata": {}, + "outputs": [], + "source": [ + "freq_wrap = _FrequencyAndConstraints(h_freq_table, h_constraint)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This wrapper returns every `cat_id` column with non zero values:\n", + "\n", + "* `0` represents households with no car and no children \n", + "* `1` represents households with no car and children \n", + "* `2` represents households with one car and no children\n", + "* `3` represents households with one car and children\n", + "* `4` represents households with two or more cars and no children\n", + "* `5` represents households with two or more cars and children\n", + "\n", + "The wrapper returns each variables combination (from 0 to 5) with a weights matrix, the new target value we built in the `ipf` and the index of non zero columns: " + ] + }, + { + "cell_type": "code", + "execution_count": 121, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[(0,\n", + " array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.]),\n", + " 46.529753144154704,\n", + " array([ 0, 1, 2, 7, 16, 18, 20, 27, 32, 34, 38,\n", + " 41, 47, 58, 60, 74, 84, 86, 87, 88, 90, 95,\n", + " 97, 99, 106, 107, 108, 115, 116, 118, 121, 122, 130,\n", + " 131, 135, 138, 140, 159, 163, 165, 169, 175, 182, 190,\n", + " 192, 205, 207, 211, 212, 214, 215, 221, 223, 226, 227,\n", + " 228, 229, 232, 235, 240, 242, 256, 261, 268, 270, 279,\n", + " 280, 281, 282, 283, 285, 287, 291, 295, 297, 298, 299,\n", + " 300, 308, 309, 310, 311, 315, 320, 324, 331, 332, 336,\n", + " 338, 345, 356, 361, 363, 366, 367, 368, 372, 380, 383,\n", + " 388, 393, 400, 403, 406, 408, 418, 419, 430, 432, 433,\n", + " 434, 449, 450, 465, 466, 471, 472, 473, 483, 486, 499,\n", + " 504, 513, 514, 519, 537, 538, 540, 545, 546, 548, 552,\n", + " 553, 559, 565, 573, 579, 580, 583, 585, 589, 590, 597,\n", + " 598, 609, 613, 622, 624, 629, 632, 635, 636, 637, 638,\n", + " 641, 642, 646, 649, 650, 660, 661, 669, 672, 673, 684,\n", + " 687, 692, 697, 698, 706, 713, 716, 725, 727, 737, 738,\n", + " 739, 741, 747, 751, 754, 761, 762, 768, 797, 804, 805,\n", + " 809, 814, 815, 820, 822, 824, 825, 826, 837, 839, 840,\n", + " 842, 847, 855, 863, 866, 868, 872, 876, 887, 891, 901,\n", + " 905, 911, 916, 917, 923, 937, 939, 942, 945, 946, 952,\n", + " 960, 967, 969, 970, 973, 974, 975, 978, 984, 989, 990,\n", + " 993, 997, 999, 1000, 1005, 1006, 1009, 1011, 1015, 1021, 1022,\n", + " 1024, 1031, 1037, 1040, 1043, 1044, 1057, 1059, 1062, 1063, 1071,\n", + " 1072, 1073, 1079, 1083, 1090, 1093, 1094, 1096, 1097, 1101, 1106,\n", + " 1107, 1108, 1114, 1118, 1124, 1130, 1137, 1138, 1140, 1143, 1144,\n", + " 1161, 1171, 1175, 1178, 1180, 1186, 1187, 1188, 1192, 1196, 1197,\n", + " 1204, 1226, 1247, 1252, 1253, 1254, 1256, 1259, 1261, 1263, 1267,\n", + " 1271, 1279, 1285, 1292, 1295, 1302, 1305, 1308, 1317, 1319, 1321,\n", + " 1324, 1331, 1333, 1335, 1354, 1355, 1357, 1358, 1361, 1362, 1366,\n", + " 1367, 1373, 1382, 1395, 1396, 1397, 1406, 1407, 1408, 1409, 1415,\n", + " 1421, 1425, 1426, 1427, 1429, 1434, 1444, 1445, 1452, 1456, 1460,\n", + " 1461, 1466, 1474, 1480, 1481, 1482, 1490, 1491, 1493, 1501, 1509,\n", + " 1521, 1528, 1545, 1552, 1566, 1567, 1570, 1576, 1577, 1580, 1582,\n", + " 1594, 1603, 1605, 1618, 1619, 1627, 1628, 1643, 1645, 1650, 1653,\n", + " 1654, 1655, 1657, 1660, 1661, 1662, 1664, 1674, 1679, 1688, 1691,\n", + " 1692, 1701, 1704, 1705, 1709, 1710, 1711, 1712, 1713, 1715, 1729,\n", + " 1730, 1731, 1738, 1739, 1741, 1746, 1751, 1766, 1770, 1779, 1783,\n", + " 1785, 1787, 1800, 1802, 1811, 1816, 1820, 1821, 1824, 1829, 1833,\n", + " 1843, 1848, 1850, 1851, 1856, 1861, 1865, 1866, 1867, 1870, 1874,\n", + " 1875, 1878, 1883, 1887, 1890, 1891, 1893, 1897, 1903, 1904, 1905,\n", + " 1907, 1917, 1918, 1920, 1923, 1924, 1932, 1934, 1937, 1947, 1953,\n", + " 1957, 1958, 1962, 1965, 1971, 1972, 1975, 1976, 1979, 1980, 1998,\n", + " 2000, 2003, 2008, 2013, 2021, 2025, 2028, 2032, 2034, 2036, 2041,\n", + " 2048, 2049, 2056, 2061, 2064, 2068, 2070, 2076, 2080, 2086, 2090,\n", + " 2093, 2096, 2102, 2112, 2120, 2124, 2131, 2132, 2133, 2138, 2144,\n", + " 2146, 2159, 2165, 2167, 2173, 2174, 2183, 2184, 2189, 2198, 2200,\n", + " 2203, 2204, 2210, 2213, 2219, 2220, 2228, 2233, 2234, 2240, 2241,\n", + " 2251, 2252, 2255, 2260, 2264, 2265, 2267, 2273, 2280, 2283, 2284,\n", + " 2285, 2286, 2289, 2291, 2293, 2294, 2295, 2297, 2309, 2313, 2314,\n", + " 2317, 2321, 2331, 2335, 2344, 2350, 2352, 2364, 2369, 2370, 2371,\n", + " 2380, 2393, 2396, 2402, 2403, 2404, 2411, 2412, 2415, 2423, 2435,\n", + " 2445, 2447, 2450, 2453, 2466, 2469, 2476, 2481, 2491, 2495, 2507,\n", + " 2513, 2514, 2518, 2519, 2527, 2530, 2532, 2535, 2536, 2539, 2542,\n", + " 2545, 2546, 2547, 2559, 2562, 2565, 2577, 2579, 2584, 2588, 2593,\n", + " 2594, 2596, 2598, 2603, 2604, 2610, 2612, 2615, 2621, 2622, 2623,\n", + " 2631, 2638, 2642, 2646, 2647, 2654, 2659, 2660, 2661, 2662, 2667,\n", + " 2671, 2677, 2684, 2686, 2688, 2689, 2692, 2694, 2701, 2702, 2703,\n", + " 2705, 2706, 2712, 2714, 2715, 2717, 2719, 2724, 2728, 2729, 2735,\n", + " 2739, 2742, 2744, 2748, 2750, 2755, 2757, 2768, 2770, 2773, 2774,\n", + " 2776, 2777, 2778, 2779, 2780, 2785, 2790, 2791, 2792, 2802, 2803,\n", + " 2806, 2812, 2818, 2824, 2828, 2829, 2831, 2848, 2849, 2857, 2858,\n", + " 2861, 2864, 2872, 2874, 2877, 2882, 2884, 2885, 2890, 2898, 2900,\n", + " 2902, 2906, 2911, 2913, 2922, 2926, 2934, 2935, 2943, 2953, 2955,\n", + " 2964, 2967, 2969, 2972, 2973, 2981, 2983, 2984, 2985, 2988, 2990,\n", + " 2996, 2997, 3002, 3009, 3010, 3012, 3024, 3025, 3030, 3035, 3036,\n", + " 3043, 3045, 3047, 3052, 3053, 3055, 3062, 3069, 3072, 3077, 3079,\n", + " 3080, 3084, 3089, 3095, 3098, 3116, 3118, 3124, 3128, 3138, 3145,\n", + " 3148, 3166, 3168, 3173, 3174, 3178, 3185, 3193, 3205, 3208, 3214,\n", + " 3218, 3232, 3237, 3240, 3247, 3256, 3259, 3262, 3263, 3266, 3267,\n", + " 3270, 3273, 3287, 3294, 3296, 3301, 3302, 3311, 3316, 3320, 3336,\n", + " 3341, 3345, 3353, 3356, 3357, 3363, 3365, 3366, 3367, 3369, 3371,\n", + " 3376, 3377, 3380, 3390, 3391, 3393, 3397, 3399, 3401, 3404, 3406,\n", + " 3410, 3415, 3419, 3421, 3424, 3429, 3431, 3432, 3443, 3444, 3457,\n", + " 3458, 3459, 3462, 3466, 3468, 3470, 3471, 3472, 3473, 3478, 3488,\n", + " 3490, 3494, 3497, 3499, 3503, 3505, 3520, 3532, 3544, 3546, 3547,\n", + " 3548, 3550, 3551, 3556, 3557, 3562, 3567, 3570, 3576, 3578, 3581,\n", + " 3582, 3596, 3611, 3616, 3617, 3618, 3623])),\n", + " (1,\n", + " array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1.]),\n", + " 46.538428452649654,\n", + " array([ 3, 6, 8, 9, 21, 28, 29, 31, 33, 43, 48,\n", + " 52, 53, 55, 56, 57, 64, 69, 70, 73, 80, 83,\n", + " 93, 96, 101, 102, 103, 111, 114, 117, 120, 126, 127,\n", + " 128, 133, 134, 136, 137, 145, 148, 157, 160, 161, 164,\n", + " 170, 172, 173, 177, 183, 188, 189, 193, 198, 199, 201,\n", + " 202, 204, 206, 216, 230, 241, 247, 249, 255, 260, 265,\n", + " 267, 275, 276, 286, 289, 292, 296, 302, 304, 313, 318,\n", + " 323, 327, 334, 335, 340, 343, 351, 370, 373, 374, 381,\n", + " 386, 392, 398, 399, 404, 405, 407, 410, 412, 415, 420,\n", + " 424, 435, 437, 442, 443, 446, 451, 452, 454, 455, 460,\n", + " 462, 470, 474, 476, 479, 484, 485, 489, 490, 497, 502,\n", + " 503, 505, 508, 512, 516, 522, 530, 531, 532, 534, 539,\n", + " 542, 554, 563, 564, 581, 584, 586, 592, 595, 599, 600,\n", + " 604, 614, 619, 621, 630, 631, 633, 647, 648, 651, 653,\n", + " 654, 657, 659, 675, 676, 678, 685, 690, 695, 701, 702,\n", + " 704, 705, 707, 708, 709, 712, 714, 715, 720, 721, 728,\n", + " 731, 735, 736, 742, 743, 744, 746, 750, 756, 757, 758,\n", + " 759, 765, 773, 778, 779, 783, 786, 787, 791, 802, 806,\n", + " 808, 813, 817, 819, 821, 823, 829, 831, 833, 834, 838,\n", + " 846, 851, 853, 857, 859, 861, 867, 873, 878, 883, 888,\n", + " 890, 893, 894, 899, 907, 908, 910, 918, 922, 924, 925,\n", + " 927, 929, 930, 931, 932, 934, 941, 947, 950, 955, 965,\n", + " 968, 971, 976, 982, 995, 998, 1001, 1016, 1017, 1018, 1026,\n", + " 1030, 1032, 1035, 1036, 1046, 1060, 1066, 1067, 1070, 1075, 1077,\n", + " 1082, 1100, 1104, 1110, 1112, 1115, 1117, 1120, 1129, 1131, 1132,\n", + " 1133, 1135, 1139, 1147, 1148, 1151, 1152, 1157, 1160, 1165, 1169,\n", + " 1183, 1189, 1194, 1202, 1210, 1213, 1214, 1220, 1224, 1227, 1233,\n", + " 1238, 1243, 1244, 1249, 1258, 1275, 1277, 1280, 1282, 1283, 1284,\n", + " 1287, 1289, 1293, 1301, 1307, 1310, 1313, 1315, 1320, 1329, 1330,\n", + " 1337, 1338, 1340, 1344, 1346, 1352, 1356, 1364, 1365, 1372, 1379,\n", + " 1384, 1394, 1402, 1405, 1412, 1414, 1418, 1419, 1424, 1428, 1431,\n", + " 1436, 1440, 1446, 1453, 1454, 1464, 1468, 1469, 1471, 1473, 1475,\n", + " 1478, 1486, 1487, 1496, 1497, 1498, 1500, 1503, 1507, 1511, 1512,\n", + " 1513, 1518, 1520, 1524, 1531, 1532, 1535, 1539, 1540, 1542, 1543,\n", + " 1553, 1557, 1560, 1563, 1568, 1578, 1581, 1584, 1585, 1587, 1589,\n", + " 1590, 1591, 1595, 1599, 1601, 1604, 1606, 1610, 1614, 1615, 1616,\n", + " 1620, 1631, 1640, 1648, 1656, 1658, 1663, 1665, 1668, 1671, 1680,\n", + " 1685, 1687, 1690, 1702, 1706, 1707, 1725, 1726, 1728, 1733, 1734,\n", + " 1736, 1740, 1750, 1754, 1755, 1760, 1762, 1769, 1773, 1775, 1778,\n", + " 1780, 1781, 1782, 1784, 1788, 1789, 1791, 1794, 1797, 1798, 1806,\n", + " 1810, 1815, 1818, 1822, 1827, 1831, 1832, 1834, 1836, 1838, 1855,\n", + " 1857, 1858, 1859, 1860, 1862, 1863, 1864, 1869, 1876, 1880, 1886,\n", + " 1888, 1894, 1899, 1901, 1909, 1913, 1915, 1919, 1921, 1925, 1926,\n", + " 1929, 1936, 1938, 1940, 1941, 1943, 1952, 1955, 1956, 1960, 1963,\n", + " 1966, 1970, 1973, 1981, 1984, 1991, 1999, 2001, 2002, 2004, 2006,\n", + " 2009, 2012, 2015, 2016, 2017, 2022, 2027, 2031, 2035, 2038, 2039,\n", + " 2047, 2051, 2055, 2063, 2065, 2067, 2071, 2077, 2079, 2083, 2084,\n", + " 2088, 2092, 2104, 2114, 2115, 2117, 2118, 2126, 2134, 2139, 2140,\n", + " 2142, 2145, 2147, 2148, 2155, 2156, 2160, 2161, 2168, 2169, 2175,\n", + " 2177, 2178, 2186, 2188, 2190, 2191, 2199, 2201, 2221, 2224, 2226,\n", + " 2229, 2230, 2232, 2239, 2243, 2246, 2247, 2248, 2249, 2250, 2254,\n", + " 2259, 2266, 2269, 2270, 2274, 2275, 2282, 2292, 2300, 2301, 2302,\n", + " 2304, 2305, 2306, 2311, 2312, 2320, 2323, 2327, 2332, 2342, 2346,\n", + " 2354, 2357, 2358, 2360, 2362, 2363, 2366, 2367, 2368, 2373, 2374,\n", + " 2375, 2376, 2377, 2379, 2382, 2385, 2388, 2392, 2397, 2399, 2407,\n", + " 2409, 2417, 2418, 2419, 2420, 2421, 2424, 2430, 2432, 2439, 2441,\n", + " 2443, 2449, 2451, 2454, 2465, 2474, 2478, 2498, 2499, 2501, 2502,\n", + " 2503, 2506, 2521, 2528, 2529, 2533, 2537, 2543, 2551, 2553, 2554,\n", + " 2556, 2564, 2569, 2572, 2573, 2576, 2578, 2580, 2585, 2587, 2600,\n", + " 2602, 2607, 2608, 2609, 2619, 2620, 2624, 2625, 2626, 2628, 2639,\n", + " 2640, 2648, 2651, 2658, 2664, 2673, 2679, 2680, 2697, 2698, 2708,\n", + " 2710, 2713, 2718, 2723, 2730, 2731, 2732, 2733, 2736, 2738, 2740,\n", + " 2741, 2743, 2746, 2749, 2751, 2752, 2756, 2761, 2766, 2767, 2782,\n", + " 2786, 2788, 2795, 2798, 2799, 2804, 2807, 2809, 2813, 2816, 2817,\n", + " 2821, 2822, 2826, 2836, 2841, 2850, 2854, 2859, 2865, 2867, 2869,\n", + " 2871, 2873, 2879, 2889, 2892, 2895, 2896, 2903, 2907, 2908, 2914,\n", + " 2917, 2923, 2927, 2929, 2932, 2936, 2941, 2946, 2948, 2949, 2957,\n", + " 2959, 2962, 2965, 2970, 2975, 2976, 2978, 2979, 2989, 2995, 2998,\n", + " 3001, 3003, 3005, 3006, 3008, 3014, 3017, 3018, 3021, 3023, 3028,\n", + " 3029, 3031, 3032, 3033, 3034, 3037, 3042, 3046, 3048, 3051, 3057,\n", + " 3063, 3066, 3074, 3081, 3083, 3085, 3103, 3106, 3113, 3114, 3121,\n", + " 3122, 3125, 3129, 3132, 3134, 3137, 3139, 3146, 3147, 3153, 3158,\n", + " 3160, 3169, 3171, 3172, 3177, 3179, 3188, 3189, 3190, 3192, 3199,\n", + " 3201, 3209, 3220, 3226, 3233, 3238, 3239, 3241, 3242, 3245, 3246,\n", + " 3249, 3250, 3251, 3252, 3253, 3254, 3260, 3261, 3264, 3265, 3268,\n", + " 3275, 3282, 3288, 3290, 3292, 3298, 3303, 3312, 3315, 3319, 3326,\n", + " 3328, 3330, 3339, 3347, 3351, 3360, 3361, 3373, 3375, 3379, 3381,\n", + " 3382, 3386, 3392, 3396, 3398, 3412, 3413, 3418, 3423, 3425, 3426,\n", + " 3430, 3433, 3434, 3436, 3442, 3447, 3452, 3456, 3461, 3465, 3474,\n", + " 3477, 3480, 3481, 3482, 3483, 3489, 3496, 3501, 3502, 3504, 3506,\n", + " 3510, 3514, 3517, 3518, 3519, 3524, 3527, 3530, 3533, 3534, 3536,\n", + " 3537, 3538, 3540, 3541, 3545, 3549, 3552, 3553, 3559, 3563, 3565,\n", + " 3566, 3572, 3575, 3577, 3579, 3580, 3583, 3586, 3587, 3597, 3598,\n", + " 3599, 3600, 3602, 3605, 3609, 3621])),\n", + " (2,\n", + " array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.]),\n", + " 27.835804541797003,\n", + " array([ 10, 11, 19, 22, 25, 26, 42, 44, 46, 71, 72,\n", + " 77, 85, 89, 94, 109, 110, 113, 123, 124, 144, 146,\n", + " 149, 151, 171, 174, 179, 184, 187, 194, 196, 197, 213,\n", + " 218, 224, 234, 243, 246, 248, 252, 253, 266, 271, 278,\n", + " 303, 307, 317, 321, 325, 333, 339, 341, 342, 357, 359,\n", + " 369, 376, 382, 395, 397, 409, 414, 416, 417, 421, 423,\n", + " 426, 436, 438, 445, 456, 457, 458, 467, 469, 480, 487,\n", + " 507, 510, 524, 527, 529, 535, 536, 547, 550, 551, 560,\n", + " 562, 566, 568, 569, 570, 571, 572, 575, 576, 582, 591,\n", + " 596, 602, 603, 605, 610, 617, 626, 644, 652, 658, 665,\n", + " 668, 670, 677, 680, 686, 689, 693, 700, 717, 726, 730,\n", + " 732, 740, 749, 753, 763, 766, 767, 772, 774, 776, 780,\n", + " 781, 785, 789, 792, 795, 810, 844, 848, 854, 856, 865,\n", + " 871, 874, 877, 881, 895, 896, 902, 903, 904, 906, 912,\n", + " 914, 915, 928, 935, 948, 957, 959, 963, 981, 986, 994,\n", + " 1014, 1020, 1025, 1045, 1055, 1065, 1099, 1123, 1134, 1136, 1141,\n", + " 1142, 1154, 1158, 1159, 1168, 1172, 1173, 1174, 1177, 1184, 1185,\n", + " 1191, 1193, 1199, 1200, 1201, 1206, 1222, 1223, 1229, 1230, 1234,\n", + " 1242, 1246, 1255, 1260, 1272, 1273, 1278, 1288, 1290, 1291, 1296,\n", + " 1316, 1325, 1326, 1334, 1336, 1343, 1345, 1348, 1350, 1353, 1359,\n", + " 1368, 1369, 1374, 1375, 1381, 1385, 1391, 1393, 1410, 1411, 1432,\n", + " 1451, 1462, 1483, 1516, 1517, 1519, 1525, 1527, 1529, 1530, 1541,\n", + " 1546, 1548, 1556, 1559, 1565, 1573, 1583, 1597, 1600, 1609, 1617,\n", + " 1621, 1624, 1625, 1629, 1633, 1634, 1642, 1646, 1647, 1649, 1651,\n", + " 1659, 1667, 1672, 1677, 1689, 1699, 1716, 1717, 1718, 1720, 1742,\n", + " 1748, 1757, 1764, 1767, 1772, 1777, 1786, 1792, 1804, 1809, 1812,\n", + " 1813, 1825, 1826, 1828, 1842, 1854, 1873, 1882, 1884, 1900, 1902,\n", + " 1906, 1911, 1935, 1942, 1948, 1951, 1954, 1964, 1968, 1988, 1993,\n", + " 1994, 1995, 1997, 2010, 2024, 2026, 2029, 2037, 2046, 2059, 2060,\n", + " 2072, 2075, 2078, 2082, 2098, 2099, 2107, 2109, 2111, 2119, 2121,\n", + " 2128, 2136, 2152, 2157, 2170, 2171, 2172, 2176, 2192, 2194, 2205,\n", + " 2215, 2217, 2218, 2222, 2223, 2225, 2236, 2242, 2261, 2276, 2277,\n", + " 2279, 2281, 2303, 2307, 2308, 2315, 2322, 2328, 2348, 2353, 2361,\n", + " 2365, 2378, 2383, 2386, 2389, 2390, 2391, 2398, 2406, 2408, 2410,\n", + " 2434, 2436, 2437, 2442, 2444, 2457, 2458, 2460, 2461, 2463, 2467,\n", + " 2480, 2486, 2493, 2497, 2505, 2508, 2510, 2522, 2524, 2526, 2534,\n", + " 2544, 2548, 2549, 2552, 2557, 2561, 2582, 2586, 2590, 2592, 2595,\n", + " 2601, 2606, 2632, 2650, 2652, 2655, 2663, 2665, 2666, 2668, 2669,\n", + " 2672, 2674, 2681, 2687, 2690, 2691, 2693, 2699, 2711, 2720, 2722,\n", + " 2727, 2734, 2745, 2747, 2758, 2759, 2769, 2771, 2772, 2775, 2781,\n", + " 2783, 2787, 2789, 2796, 2810, 2811, 2820, 2827, 2833, 2839, 2840,\n", + " 2842, 2843, 2847, 2853, 2860, 2875, 2876, 2881, 2888, 2894, 2901,\n", + " 2904, 2916, 2919, 2928, 2950, 2954, 2960, 2963, 2966, 2986, 2987,\n", + " 2992, 2994, 2999, 3000, 3007, 3039, 3059, 3061, 3064, 3067, 3073,\n", + " 3078, 3082, 3087, 3088, 3090, 3099, 3104, 3112, 3126, 3127, 3131,\n", + " 3135, 3144, 3149, 3150, 3154, 3155, 3157, 3162, 3170, 3175, 3180,\n", + " 3181, 3182, 3183, 3184, 3187, 3197, 3204, 3210, 3216, 3221, 3225,\n", + " 3227, 3230, 3235, 3236, 3243, 3244, 3271, 3272, 3276, 3278, 3283,\n", + " 3289, 3293, 3304, 3305, 3306, 3307, 3318, 3324, 3329, 3346, 3348,\n", + " 3350, 3352, 3358, 3362, 3383, 3385, 3388, 3405, 3408, 3422, 3437,\n", + " 3439, 3446, 3448, 3450, 3486, 3507, 3512, 3513, 3516, 3522, 3523,\n", + " 3554, 3560, 3569, 3573, 3574, 3584, 3593, 3595, 3601, 3606, 3613,\n", + " 3614])),\n", + " (3,\n", + " array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1.]),\n", + " 19.20965012246301,\n", + " array([ 4, 5, 13, 30, 54, 59, 61, 76, 78, 82, 98,\n", + " 104, 112, 129, 132, 142, 143, 152, 155, 156, 167, 168,\n", + " 180, 181, 185, 203, 209, 222, 225, 239, 245, 251, 258,\n", + " 262, 269, 272, 284, 290, 305, 312, 316, 337, 347, 349,\n", + " 350, 352, 354, 362, 377, 385, 394, 413, 422, 425, 428,\n", + " 429, 439, 440, 441, 447, 448, 453, 459, 463, 464, 488,\n", + " 492, 496, 500, 509, 520, 521, 523, 525, 526, 533, 549,\n", + " 557, 558, 567, 574, 587, 593, 606, 607, 625, 627, 634,\n", + " 655, 663, 667, 674, 679, 683, 696, 718, 719, 729, 748,\n", + " 760, 769, 796, 800, 801, 807, 816, 818, 832, 835, 850,\n", + " 858, 862, 870, 875, 880, 884, 886, 889, 892, 897, 920,\n", + " 940, 944, 954, 958, 979, 985, 988, 991, 1002, 1010, 1027,\n", + " 1028, 1033, 1039, 1041, 1050, 1052, 1053, 1084, 1085, 1098, 1103,\n", + " 1109, 1116, 1122, 1146, 1156, 1163, 1166, 1170, 1190, 1195, 1203,\n", + " 1209, 1215, 1216, 1221, 1237, 1248, 1251, 1265, 1266, 1268, 1274,\n", + " 1298, 1304, 1318, 1322, 1347, 1349, 1377, 1390, 1392, 1404, 1417,\n", + " 1420, 1430, 1433, 1438, 1441, 1443, 1448, 1449, 1457, 1458, 1459,\n", + " 1465, 1476, 1485, 1488, 1502, 1510, 1515, 1523, 1533, 1536, 1538,\n", + " 1558, 1571, 1574, 1579, 1586, 1592, 1593, 1602, 1607, 1623, 1632,\n", + " 1636, 1637, 1638, 1639, 1652, 1670, 1673, 1682, 1683, 1684, 1698,\n", + " 1719, 1735, 1744, 1745, 1752, 1756, 1763, 1768, 1776, 1790, 1795,\n", + " 1796, 1807, 1823, 1830, 1837, 1839, 1840, 1841, 1852, 1877, 1879,\n", + " 1889, 1930, 1939, 1944, 1945, 1959, 1969, 1978, 1985, 1987, 1996,\n", + " 2007, 2014, 2018, 2030, 2043, 2044, 2066, 2081, 2095, 2101, 2105,\n", + " 2108, 2125, 2129, 2137, 2143, 2150, 2153, 2185, 2196, 2206, 2212,\n", + " 2214, 2216, 2231, 2235, 2262, 2272, 2278, 2298, 2310, 2318, 2324,\n", + " 2333, 2343, 2359, 2372, 2381, 2394, 2395, 2400, 2425, 2429, 2446,\n", + " 2462, 2470, 2471, 2472, 2475, 2477, 2484, 2485, 2487, 2488, 2489,\n", + " 2511, 2523, 2538, 2541, 2563, 2568, 2617, 2629, 2644, 2649, 2670,\n", + " 2676, 2683, 2685, 2695, 2696, 2819, 2823, 2825, 2830, 2834, 2838,\n", + " 2846, 2863, 2870, 2883, 2893, 2910, 2912, 2921, 2930, 2931, 2933,\n", + " 2939, 2940, 2942, 2945, 2958, 2971, 2980, 3013, 3015, 3016, 3019,\n", + " 3026, 3027, 3049, 3050, 3060, 3076, 3086, 3092, 3093, 3094, 3096,\n", + " 3100, 3110, 3115, 3120, 3130, 3133, 3136, 3141, 3143, 3159, 3165,\n", + " 3186, 3191, 3195, 3198, 3202, 3211, 3215, 3222, 3223, 3228, 3229,\n", + " 3234, 3248, 3257, 3258, 3280, 3281, 3286, 3291, 3314, 3317, 3325,\n", + " 3327, 3340, 3355, 3368, 3370, 3387, 3395, 3402, 3407, 3414, 3417,\n", + " 3420, 3428, 3435, 3451, 3454, 3455, 3464, 3479, 3487, 3491, 3493,\n", + " 3495, 3535, 3558, 3564, 3590, 3592, 3607, 3610, 3612, 3615, 3619,\n", + " 3620, 3624])),\n", + " (4,\n", + " array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.]),\n", + " 23.6344423140483,\n", + " array([ 17, 23, 24, 36, 37, 39, 40, 50, 62, 66, 67,\n", + " 75, 81, 91, 92, 100, 119, 125, 158, 162, 166, 176,\n", + " 186, 191, 195, 200, 208, 210, 220, 233, 237, 244, 250,\n", + " 257, 259, 263, 273, 293, 294, 314, 319, 322, 330, 344,\n", + " 348, 353, 360, 387, 401, 402, 461, 468, 475, 478, 482,\n", + " 493, 494, 495, 498, 501, 506, 511, 515, 518, 528, 541,\n", + " 556, 561, 577, 578, 601, 611, 612, 615, 618, 620, 623,\n", + " 640, 645, 656, 664, 666, 681, 688, 691, 694, 699, 710,\n", + " 711, 722, 723, 724, 733, 734, 745, 755, 764, 770, 771,\n", + " 777, 790, 794, 799, 803, 812, 830, 836, 841, 843, 849,\n", + " 852, 860, 879, 882, 885, 900, 909, 919, 926, 933, 936,\n", + " 943, 951, 956, 961, 964, 980, 983, 992, 1007, 1012, 1013,\n", + " 1029, 1034, 1047, 1048, 1051, 1054, 1056, 1058, 1061, 1064, 1080,\n", + " 1081, 1086, 1087, 1088, 1091, 1092, 1095, 1111, 1113, 1119, 1121,\n", + " 1125, 1126, 1127, 1145, 1149, 1150, 1164, 1167, 1176, 1181, 1205,\n", + " 1207, 1208, 1219, 1228, 1235, 1236, 1239, 1240, 1250, 1264, 1276,\n", + " 1299, 1300, 1303, 1306, 1311, 1314, 1328, 1332, 1342, 1351, 1363,\n", + " 1370, 1371, 1376, 1380, 1386, 1387, 1398, 1399, 1403, 1422, 1423,\n", + " 1435, 1437, 1439, 1442, 1447, 1467, 1470, 1472, 1479, 1489, 1492,\n", + " 1499, 1504, 1508, 1514, 1526, 1537, 1547, 1551, 1555, 1561, 1562,\n", + " 1564, 1575, 1596, 1608, 1611, 1612, 1635, 1641, 1675, 1676, 1678,\n", + " 1681, 1693, 1694, 1695, 1696, 1697, 1700, 1703, 1714, 1721, 1722,\n", + " 1723, 1732, 1747, 1753, 1758, 1759, 1761, 1765, 1774, 1805, 1819,\n", + " 1844, 1845, 1846, 1847, 1849, 1871, 1881, 1885, 1892, 1898, 1908,\n", + " 1910, 1927, 1928, 1949, 1950, 1961, 1967, 1977, 1982, 1983, 1986,\n", + " 1989, 1990, 2011, 2019, 2020, 2023, 2040, 2042, 2045, 2050, 2054,\n", + " 2057, 2058, 2085, 2087, 2097, 2100, 2106, 2110, 2123, 2130, 2141,\n", + " 2151, 2158, 2163, 2179, 2187, 2193, 2195, 2197, 2202, 2207, 2208,\n", + " 2227, 2237, 2238, 2244, 2256, 2258, 2263, 2287, 2299, 2319, 2325,\n", + " 2326, 2329, 2330, 2336, 2340, 2345, 2384, 2387, 2401, 2414, 2416,\n", + " 2426, 2427, 2431, 2433, 2452, 2456, 2459, 2468, 2483, 2492, 2494,\n", + " 2496, 2500, 2504, 2512, 2515, 2516, 2520, 2525, 2540, 2560, 2566,\n", + " 2567, 2570, 2571, 2581, 2599, 2605, 2613, 2616, 2630, 2634, 2635,\n", + " 2637, 2641, 2645, 2653, 2656, 2657, 2675, 2678, 2709, 2725, 2737,\n", + " 2753, 2760, 2762, 2763, 2784, 2797, 2800, 2801, 2808, 2815, 2832,\n", + " 2837, 2844, 2845, 2851, 2868, 2880, 2886, 2887, 2897, 2899, 2905,\n", + " 2915, 2925, 2937, 2938, 2944, 2947, 2951, 2952, 2956, 2961, 2968,\n", + " 2977, 2991, 3004, 3038, 3058, 3065, 3068, 3070, 3071, 3075, 3097,\n", + " 3102, 3105, 3109, 3117, 3119, 3123, 3140, 3152, 3161, 3163, 3164,\n", + " 3167, 3176, 3194, 3196, 3200, 3207, 3212, 3219, 3224, 3255, 3274,\n", + " 3277, 3279, 3284, 3285, 3295, 3297, 3299, 3300, 3308, 3310, 3321,\n", + " 3322, 3323, 3333, 3334, 3337, 3338, 3343, 3344, 3354, 3364, 3372,\n", + " 3378, 3384, 3394, 3409, 3411, 3416, 3427, 3438, 3440, 3441, 3449,\n", + " 3463, 3469, 3475, 3476, 3484, 3485, 3508, 3509, 3511, 3528, 3531,\n", + " 3539, 3542, 3555, 3561, 3603, 3608, 3622])),\n", + " (5,\n", + " array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.]),\n", + " 16.251921424887335,\n", + " array([ 12, 14, 15, 35, 45, 49, 51, 63, 65, 68, 79,\n", + " 105, 139, 141, 147, 150, 153, 154, 178, 217, 219, 231,\n", + " 236, 238, 254, 264, 274, 277, 288, 301, 306, 326, 328,\n", + " 329, 346, 355, 358, 364, 365, 371, 375, 378, 379, 384,\n", + " 389, 390, 391, 396, 411, 427, 431, 444, 477, 481, 491,\n", + " 517, 543, 544, 555, 588, 594, 608, 616, 628, 639, 643,\n", + " 662, 671, 682, 703, 752, 775, 782, 784, 788, 793, 798,\n", + " 811, 827, 828, 845, 864, 869, 898, 913, 921, 938, 949,\n", + " 953, 962, 966, 972, 977, 987, 996, 1003, 1004, 1008, 1019,\n", + " 1023, 1038, 1042, 1049, 1068, 1069, 1074, 1076, 1078, 1089, 1102,\n", + " 1105, 1128, 1153, 1155, 1162, 1179, 1182, 1198, 1211, 1212, 1217,\n", + " 1218, 1225, 1231, 1232, 1241, 1245, 1257, 1262, 1269, 1270, 1281,\n", + " 1286, 1294, 1297, 1309, 1312, 1323, 1327, 1339, 1341, 1360, 1378,\n", + " 1383, 1388, 1389, 1400, 1401, 1413, 1416, 1450, 1455, 1463, 1477,\n", + " 1484, 1494, 1495, 1505, 1506, 1522, 1534, 1544, 1549, 1550, 1554,\n", + " 1569, 1572, 1588, 1598, 1613, 1622, 1626, 1630, 1644, 1666, 1669,\n", + " 1686, 1708, 1724, 1727, 1737, 1743, 1749, 1771, 1793, 1799, 1801,\n", + " 1803, 1808, 1814, 1817, 1835, 1853, 1868, 1872, 1895, 1896, 1912,\n", + " 1914, 1916, 1922, 1931, 1933, 1946, 1974, 1992, 2005, 2033, 2052,\n", + " 2053, 2062, 2069, 2073, 2074, 2089, 2091, 2094, 2103, 2113, 2116,\n", + " 2122, 2127, 2135, 2149, 2154, 2162, 2164, 2166, 2180, 2181, 2182,\n", + " 2209, 2211, 2245, 2253, 2257, 2268, 2271, 2288, 2290, 2296, 2316,\n", + " 2334, 2337, 2338, 2339, 2341, 2347, 2349, 2351, 2355, 2356, 2405,\n", + " 2413, 2422, 2428, 2438, 2440, 2448, 2455, 2464, 2473, 2479, 2482,\n", + " 2490, 2509, 2517, 2531, 2550, 2555, 2558, 2574, 2575, 2583, 2589,\n", + " 2591, 2597, 2611, 2614, 2618, 2627, 2633, 2636, 2643, 2682, 2700,\n", + " 2704, 2707, 2716, 2721, 2726, 2754, 2764, 2765, 2793, 2794, 2805,\n", + " 2814, 2835, 2852, 2855, 2856, 2862, 2866, 2878, 2891, 2909, 2918,\n", + " 2920, 2924, 2974, 2982, 2993, 3011, 3020, 3022, 3040, 3041, 3044,\n", + " 3054, 3056, 3091, 3101, 3107, 3108, 3111, 3142, 3151, 3156, 3203,\n", + " 3206, 3213, 3217, 3231, 3269, 3309, 3313, 3331, 3332, 3335, 3342,\n", + " 3349, 3359, 3374, 3389, 3400, 3403, 3445, 3453, 3460, 3467, 3492,\n", + " 3498, 3500, 3515, 3521, 3525, 3526, 3529, 3543, 3568, 3571, 3585,\n", + " 3588, 3589, 3591, 3594, 3604]))]" + ] + }, + "execution_count": 121, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# here the information for all the combinations\n", + "freq_wrap.iter_columns()" + ] + }, + { + "cell_type": "code", + "execution_count": 133, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(0,\n", + " array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.]),\n", + " 46.529753144154704,\n", + " array([ 0, 1, 2, 7, 16, 18, 20, 27, 32, 34, 38,\n", + " 41, 47, 58, 60, 74, 84, 86, 87, 88, 90, 95,\n", + " 97, 99, 106, 107, 108, 115, 116, 118, 121, 122, 130,\n", + " 131, 135, 138, 140, 159, 163, 165, 169, 175, 182, 190,\n", + " 192, 205, 207, 211, 212, 214, 215, 221, 223, 226, 227,\n", + " 228, 229, 232, 235, 240, 242, 256, 261, 268, 270, 279,\n", + " 280, 281, 282, 283, 285, 287, 291, 295, 297, 298, 299,\n", + " 300, 308, 309, 310, 311, 315, 320, 324, 331, 332, 336,\n", + " 338, 345, 356, 361, 363, 366, 367, 368, 372, 380, 383,\n", + " 388, 393, 400, 403, 406, 408, 418, 419, 430, 432, 433,\n", + " 434, 449, 450, 465, 466, 471, 472, 473, 483, 486, 499,\n", + " 504, 513, 514, 519, 537, 538, 540, 545, 546, 548, 552,\n", + " 553, 559, 565, 573, 579, 580, 583, 585, 589, 590, 597,\n", + " 598, 609, 613, 622, 624, 629, 632, 635, 636, 637, 638,\n", + " 641, 642, 646, 649, 650, 660, 661, 669, 672, 673, 684,\n", + " 687, 692, 697, 698, 706, 713, 716, 725, 727, 737, 738,\n", + " 739, 741, 747, 751, 754, 761, 762, 768, 797, 804, 805,\n", + " 809, 814, 815, 820, 822, 824, 825, 826, 837, 839, 840,\n", + " 842, 847, 855, 863, 866, 868, 872, 876, 887, 891, 901,\n", + " 905, 911, 916, 917, 923, 937, 939, 942, 945, 946, 952,\n", + " 960, 967, 969, 970, 973, 974, 975, 978, 984, 989, 990,\n", + " 993, 997, 999, 1000, 1005, 1006, 1009, 1011, 1015, 1021, 1022,\n", + " 1024, 1031, 1037, 1040, 1043, 1044, 1057, 1059, 1062, 1063, 1071,\n", + " 1072, 1073, 1079, 1083, 1090, 1093, 1094, 1096, 1097, 1101, 1106,\n", + " 1107, 1108, 1114, 1118, 1124, 1130, 1137, 1138, 1140, 1143, 1144,\n", + " 1161, 1171, 1175, 1178, 1180, 1186, 1187, 1188, 1192, 1196, 1197,\n", + " 1204, 1226, 1247, 1252, 1253, 1254, 1256, 1259, 1261, 1263, 1267,\n", + " 1271, 1279, 1285, 1292, 1295, 1302, 1305, 1308, 1317, 1319, 1321,\n", + " 1324, 1331, 1333, 1335, 1354, 1355, 1357, 1358, 1361, 1362, 1366,\n", + " 1367, 1373, 1382, 1395, 1396, 1397, 1406, 1407, 1408, 1409, 1415,\n", + " 1421, 1425, 1426, 1427, 1429, 1434, 1444, 1445, 1452, 1456, 1460,\n", + " 1461, 1466, 1474, 1480, 1481, 1482, 1490, 1491, 1493, 1501, 1509,\n", + " 1521, 1528, 1545, 1552, 1566, 1567, 1570, 1576, 1577, 1580, 1582,\n", + " 1594, 1603, 1605, 1618, 1619, 1627, 1628, 1643, 1645, 1650, 1653,\n", + " 1654, 1655, 1657, 1660, 1661, 1662, 1664, 1674, 1679, 1688, 1691,\n", + " 1692, 1701, 1704, 1705, 1709, 1710, 1711, 1712, 1713, 1715, 1729,\n", + " 1730, 1731, 1738, 1739, 1741, 1746, 1751, 1766, 1770, 1779, 1783,\n", + " 1785, 1787, 1800, 1802, 1811, 1816, 1820, 1821, 1824, 1829, 1833,\n", + " 1843, 1848, 1850, 1851, 1856, 1861, 1865, 1866, 1867, 1870, 1874,\n", + " 1875, 1878, 1883, 1887, 1890, 1891, 1893, 1897, 1903, 1904, 1905,\n", + " 1907, 1917, 1918, 1920, 1923, 1924, 1932, 1934, 1937, 1947, 1953,\n", + " 1957, 1958, 1962, 1965, 1971, 1972, 1975, 1976, 1979, 1980, 1998,\n", + " 2000, 2003, 2008, 2013, 2021, 2025, 2028, 2032, 2034, 2036, 2041,\n", + " 2048, 2049, 2056, 2061, 2064, 2068, 2070, 2076, 2080, 2086, 2090,\n", + " 2093, 2096, 2102, 2112, 2120, 2124, 2131, 2132, 2133, 2138, 2144,\n", + " 2146, 2159, 2165, 2167, 2173, 2174, 2183, 2184, 2189, 2198, 2200,\n", + " 2203, 2204, 2210, 2213, 2219, 2220, 2228, 2233, 2234, 2240, 2241,\n", + " 2251, 2252, 2255, 2260, 2264, 2265, 2267, 2273, 2280, 2283, 2284,\n", + " 2285, 2286, 2289, 2291, 2293, 2294, 2295, 2297, 2309, 2313, 2314,\n", + " 2317, 2321, 2331, 2335, 2344, 2350, 2352, 2364, 2369, 2370, 2371,\n", + " 2380, 2393, 2396, 2402, 2403, 2404, 2411, 2412, 2415, 2423, 2435,\n", + " 2445, 2447, 2450, 2453, 2466, 2469, 2476, 2481, 2491, 2495, 2507,\n", + " 2513, 2514, 2518, 2519, 2527, 2530, 2532, 2535, 2536, 2539, 2542,\n", + " 2545, 2546, 2547, 2559, 2562, 2565, 2577, 2579, 2584, 2588, 2593,\n", + " 2594, 2596, 2598, 2603, 2604, 2610, 2612, 2615, 2621, 2622, 2623,\n", + " 2631, 2638, 2642, 2646, 2647, 2654, 2659, 2660, 2661, 2662, 2667,\n", + " 2671, 2677, 2684, 2686, 2688, 2689, 2692, 2694, 2701, 2702, 2703,\n", + " 2705, 2706, 2712, 2714, 2715, 2717, 2719, 2724, 2728, 2729, 2735,\n", + " 2739, 2742, 2744, 2748, 2750, 2755, 2757, 2768, 2770, 2773, 2774,\n", + " 2776, 2777, 2778, 2779, 2780, 2785, 2790, 2791, 2792, 2802, 2803,\n", + " 2806, 2812, 2818, 2824, 2828, 2829, 2831, 2848, 2849, 2857, 2858,\n", + " 2861, 2864, 2872, 2874, 2877, 2882, 2884, 2885, 2890, 2898, 2900,\n", + " 2902, 2906, 2911, 2913, 2922, 2926, 2934, 2935, 2943, 2953, 2955,\n", + " 2964, 2967, 2969, 2972, 2973, 2981, 2983, 2984, 2985, 2988, 2990,\n", + " 2996, 2997, 3002, 3009, 3010, 3012, 3024, 3025, 3030, 3035, 3036,\n", + " 3043, 3045, 3047, 3052, 3053, 3055, 3062, 3069, 3072, 3077, 3079,\n", + " 3080, 3084, 3089, 3095, 3098, 3116, 3118, 3124, 3128, 3138, 3145,\n", + " 3148, 3166, 3168, 3173, 3174, 3178, 3185, 3193, 3205, 3208, 3214,\n", + " 3218, 3232, 3237, 3240, 3247, 3256, 3259, 3262, 3263, 3266, 3267,\n", + " 3270, 3273, 3287, 3294, 3296, 3301, 3302, 3311, 3316, 3320, 3336,\n", + " 3341, 3345, 3353, 3356, 3357, 3363, 3365, 3366, 3367, 3369, 3371,\n", + " 3376, 3377, 3380, 3390, 3391, 3393, 3397, 3399, 3401, 3404, 3406,\n", + " 3410, 3415, 3419, 3421, 3424, 3429, 3431, 3432, 3443, 3444, 3457,\n", + " 3458, 3459, 3462, 3466, 3468, 3470, 3471, 3472, 3473, 3478, 3488,\n", + " 3490, 3494, 3497, 3499, 3503, 3505, 3520, 3532, 3544, 3546, 3547,\n", + " 3548, 3550, 3551, 3556, 3557, 3562, 3567, 3570, 3576, 3578, 3581,\n", + " 3582, 3596, 3611, 3616, 3617, 3618, 3623]))" + ] + }, + "execution_count": 133, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# and here, we can see for category \"0\" that non zero values are...\n", + "freq_wrap.get_column(0)" + ] + }, + { + "cell_type": "code", + "execution_count": 135, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "hh_id\n", + "0 1.0\n", + "2 1.0\n", + "3 1.0\n", + "4 0.0\n", + "5 0.0\n", + "13 0.0\n", + "14 0.0\n", + "15 1.0\n", + "Name: 0, dtype: float64" + ] + }, + "execution_count": 135, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "#... in the index 0, 1, 2, 7, (...)\n", + "h_freq_table[0][0:8]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 93, + "metadata": {}, + "outputs": [], + "source": [ + "def _drop_zeros(df):\n", + " \"\"\"\n", + " Drop zeros from a DataFrame, returning an iterator over the columns\n", + " in the DataFrame.\n", + "\n", + " Yields tuples of (column name, non-zero column values, non-zero indexes).\n", + "\n", + " Parameters\n", + " ----------\n", + " df : pandas.DataFrame\n", + "\n", + " \"\"\"\n", + " def for_each_col(col):\n", + " nz = col.nonzero()[0]\n", + " return col[nz], nz\n", + "\n", + " for (col_idx, (col, nz)) in df.apply(for_each_col, axis=0, raw=True).items():\n", + " return (col_idx, col, nz)" + ] + }, + { + "cell_type": "code", + "execution_count": 94, + "metadata": {}, + "outputs": [], + "source": [ + "df = h_freq_table.copy()" + ] + }, + { + "cell_type": "code", + "execution_count": 95, + "metadata": {}, + "outputs": [], + "source": [ + "def for_each_col(col):\n", + " nz = col.nonzero()[0]\n", + " return col[nz], nz" + ] + }, + { + "cell_type": "code", + "execution_count": 102, + "metadata": {}, + "outputs": [], + "source": [ + "for (col_idx, (col, nz)) in df.apply(for_each_col, axis=0, raw=True).items():\n", + " d = (col_idx, col, nz)" + ] + }, + { + "cell_type": "code", + "execution_count": 136, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(5,\n", + " array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.]),\n", + " array([ 12, 14, 15, 35, 45, 49, 51, 63, 65, 68, 79,\n", + " 105, 139, 141, 147, 150, 153, 154, 178, 217, 219, 231,\n", + " 236, 238, 254, 264, 274, 277, 288, 301, 306, 326, 328,\n", + " 329, 346, 355, 358, 364, 365, 371, 375, 378, 379, 384,\n", + " 389, 390, 391, 396, 411, 427, 431, 444, 477, 481, 491,\n", + " 517, 543, 544, 555, 588, 594, 608, 616, 628, 639, 643,\n", + " 662, 671, 682, 703, 752, 775, 782, 784, 788, 793, 798,\n", + " 811, 827, 828, 845, 864, 869, 898, 913, 921, 938, 949,\n", + " 953, 962, 966, 972, 977, 987, 996, 1003, 1004, 1008, 1019,\n", + " 1023, 1038, 1042, 1049, 1068, 1069, 1074, 1076, 1078, 1089, 1102,\n", + " 1105, 1128, 1153, 1155, 1162, 1179, 1182, 1198, 1211, 1212, 1217,\n", + " 1218, 1225, 1231, 1232, 1241, 1245, 1257, 1262, 1269, 1270, 1281,\n", + " 1286, 1294, 1297, 1309, 1312, 1323, 1327, 1339, 1341, 1360, 1378,\n", + " 1383, 1388, 1389, 1400, 1401, 1413, 1416, 1450, 1455, 1463, 1477,\n", + " 1484, 1494, 1495, 1505, 1506, 1522, 1534, 1544, 1549, 1550, 1554,\n", + " 1569, 1572, 1588, 1598, 1613, 1622, 1626, 1630, 1644, 1666, 1669,\n", + " 1686, 1708, 1724, 1727, 1737, 1743, 1749, 1771, 1793, 1799, 1801,\n", + " 1803, 1808, 1814, 1817, 1835, 1853, 1868, 1872, 1895, 1896, 1912,\n", + " 1914, 1916, 1922, 1931, 1933, 1946, 1974, 1992, 2005, 2033, 2052,\n", + " 2053, 2062, 2069, 2073, 2074, 2089, 2091, 2094, 2103, 2113, 2116,\n", + " 2122, 2127, 2135, 2149, 2154, 2162, 2164, 2166, 2180, 2181, 2182,\n", + " 2209, 2211, 2245, 2253, 2257, 2268, 2271, 2288, 2290, 2296, 2316,\n", + " 2334, 2337, 2338, 2339, 2341, 2347, 2349, 2351, 2355, 2356, 2405,\n", + " 2413, 2422, 2428, 2438, 2440, 2448, 2455, 2464, 2473, 2479, 2482,\n", + " 2490, 2509, 2517, 2531, 2550, 2555, 2558, 2574, 2575, 2583, 2589,\n", + " 2591, 2597, 2611, 2614, 2618, 2627, 2633, 2636, 2643, 2682, 2700,\n", + " 2704, 2707, 2716, 2721, 2726, 2754, 2764, 2765, 2793, 2794, 2805,\n", + " 2814, 2835, 2852, 2855, 2856, 2862, 2866, 2878, 2891, 2909, 2918,\n", + " 2920, 2924, 2974, 2982, 2993, 3011, 3020, 3022, 3040, 3041, 3044,\n", + " 3054, 3056, 3091, 3101, 3107, 3108, 3111, 3142, 3151, 3156, 3203,\n", + " 3206, 3213, 3217, 3231, 3269, 3309, 3313, 3331, 3332, 3335, 3342,\n", + " 3349, 3359, 3374, 3389, 3400, 3403, 3445, 3453, 3460, 3467, 3492,\n", + " 3498, 3500, 3515, 3521, 3525, 3526, 3529, 3543, 3568, 3571, 3585,\n", + " 3588, 3589, 3591, 3594, 3604]))" + ] + }, + "execution_count": 136, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "d" + ] + }, + { + "cell_type": "code", + "execution_count": 141, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "hh_id\n", + "0 0.0\n", + "2 0.0\n", + "3 0.0\n", + "4 0.0\n", + "5 0.0\n", + "13 0.0\n", + "14 0.0\n", + "15 0.0\n", + "17 0.0\n", + "18 0.0\n", + "19 0.0\n", + "23 0.0\n", + "24 1.0\n", + "25 0.0\n", + "26 1.0\n", + "Name: 5, dtype: float64" + ] + }, + "execution_count": 141, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "h_freq_table[5][:15]" + ] + }, + { + "cell_type": "code", + "execution_count": 104, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(5,\n", + " array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.]),\n", + " array([ 12, 14, 15, 35, 45, 49, 51, 63, 65, 68, 79,\n", + " 105, 139, 141, 147, 150, 153, 154, 178, 217, 219, 231,\n", + " 236, 238, 254, 264, 274, 277, 288, 301, 306, 326, 328,\n", + " 329, 346, 355, 358, 364, 365, 371, 375, 378, 379, 384,\n", + " 389, 390, 391, 396, 411, 427, 431, 444, 477, 481, 491,\n", + " 517, 543, 544, 555, 588, 594, 608, 616, 628, 639, 643,\n", + " 662, 671, 682, 703, 752, 775, 782, 784, 788, 793, 798,\n", + " 811, 827, 828, 845, 864, 869, 898, 913, 921, 938, 949,\n", + " 953, 962, 966, 972, 977, 987, 996, 1003, 1004, 1008, 1019,\n", + " 1023, 1038, 1042, 1049, 1068, 1069, 1074, 1076, 1078, 1089, 1102,\n", + " 1105, 1128, 1153, 1155, 1162, 1179, 1182, 1198, 1211, 1212, 1217,\n", + " 1218, 1225, 1231, 1232, 1241, 1245, 1257, 1262, 1269, 1270, 1281,\n", + " 1286, 1294, 1297, 1309, 1312, 1323, 1327, 1339, 1341, 1360, 1378,\n", + " 1383, 1388, 1389, 1400, 1401, 1413, 1416, 1450, 1455, 1463, 1477,\n", + " 1484, 1494, 1495, 1505, 1506, 1522, 1534, 1544, 1549, 1550, 1554,\n", + " 1569, 1572, 1588, 1598, 1613, 1622, 1626, 1630, 1644, 1666, 1669,\n", + " 1686, 1708, 1724, 1727, 1737, 1743, 1749, 1771, 1793, 1799, 1801,\n", + " 1803, 1808, 1814, 1817, 1835, 1853, 1868, 1872, 1895, 1896, 1912,\n", + " 1914, 1916, 1922, 1931, 1933, 1946, 1974, 1992, 2005, 2033, 2052,\n", + " 2053, 2062, 2069, 2073, 2074, 2089, 2091, 2094, 2103, 2113, 2116,\n", + " 2122, 2127, 2135, 2149, 2154, 2162, 2164, 2166, 2180, 2181, 2182,\n", + " 2209, 2211, 2245, 2253, 2257, 2268, 2271, 2288, 2290, 2296, 2316,\n", + " 2334, 2337, 2338, 2339, 2341, 2347, 2349, 2351, 2355, 2356, 2405,\n", + " 2413, 2422, 2428, 2438, 2440, 2448, 2455, 2464, 2473, 2479, 2482,\n", + " 2490, 2509, 2517, 2531, 2550, 2555, 2558, 2574, 2575, 2583, 2589,\n", + " 2591, 2597, 2611, 2614, 2618, 2627, 2633, 2636, 2643, 2682, 2700,\n", + " 2704, 2707, 2716, 2721, 2726, 2754, 2764, 2765, 2793, 2794, 2805,\n", + " 2814, 2835, 2852, 2855, 2856, 2862, 2866, 2878, 2891, 2909, 2918,\n", + " 2920, 2924, 2974, 2982, 2993, 3011, 3020, 3022, 3040, 3041, 3044,\n", + " 3054, 3056, 3091, 3101, 3107, 3108, 3111, 3142, 3151, 3156, 3203,\n", + " 3206, 3213, 3217, 3231, 3269, 3309, 3313, 3331, 3332, 3335, 3342,\n", + " 3349, 3359, 3374, 3389, 3400, 3403, 3445, 3453, 3460, 3467, 3492,\n", + " 3498, 3500, 3515, 3521, 3525, 3526, 3529, 3543, 3568, 3571, 3585,\n", + " 3588, 3589, 3591, 3594, 3604]))" + ] + }, + "execution_count": 104, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "d" + ] }, { "cell_type": "code", From f041f896c17b0aaa8d7c6a08a370e0ea31559ac3 Mon Sep 17 00:00:00 2001 From: PyMap Date: Tue, 28 Jul 2020 18:42:11 -0300 Subject: [PATCH 11/12] draw households --- demos/Synthesis workflow.ipynb | 4281 +++----------------------------- 1 file changed, 376 insertions(+), 3905 deletions(-) diff --git a/demos/Synthesis workflow.ipynb b/demos/Synthesis workflow.ipynb index 60ff2b5..69ffaaf 100644 --- a/demos/Synthesis workflow.ipynb +++ b/demos/Synthesis workflow.ipynb @@ -26,7 +26,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "DIAGRAM 0 HERE: synthesize all" + "![Synthesis](img/hor_synthesis.png)" ] }, { @@ -40,7 +40,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "DEFINITION HERE: ESTO ES LO QUE VAMOS A ANALIZAR, PERO QUE SIGNIFICA? REPRESENTA ALGO EN PARTICULAR? COMO SE INTERPRETA ESTA TABLA?" + "`hh` and `p` synthesis datasets are built based on PUMA geographies. The dataset paths shows a `state`, followed by a `county` and an `acs` based year. In the following example, we see synthetic households and persons for the state of Alaska and all the counties that are inside the state. \n", + "\n", + "The main idea of this process is to use the public user microdata survey (PUMS) which is a sample of the acs answers provided at the maximum dissaggrgated geography as possible (the PUMA) and use it to match each record within a `block group`. Using PUMS and acs subject tables it is possible to build different household types and match persons to them, building a dataset that will show individual records following different characteristics (race of head, tenure, children, etc, etc) " ] }, { @@ -461,7 +463,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -471,17 +473,9 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "['acsyear', 'c', 'county', 'get_available_geography_ids', 'get_geography_name', 'get_household_joint_dist_for_geography', 'get_household_marginal_for_geography', 'get_num_geographies', 'get_person_joint_dist_for_geography', 'get_person_marginal_for_geography', 'h_acs', 'h_acs_cat', 'h_pums_cols', 'p_acs', 'p_acs_cat', 'p_pums_cols', 'state', 'tract']\n" - ] - } - ], + "outputs": [], "source": [ "# what do we get from starter class?\n", "print([m for m in dir(starter) if not m.startswith('__')])" @@ -496,20 +490,9 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "('02', '290')" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "# ...state and county pair\n", "starter.state, starter.county" @@ -538,143 +521,16 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
NAMEB19001_001EB19001_002EB19001_003EB19001_004EB19001_005EB19001_006EB19001_007EB19001_008EB19001_009E...B08201_002EB08201_003EB08201_004EB08201_005EB08201_006EB08202_001EB08202_002EB08202_003EB08202_004EB08202_005E
0Block Group 1, Census Tract 1, Yukon-Koyukuk C...187521320112012118...1194016371878974212
1Block Group 2, Census Tract 1, Yukon-Koyukuk C...33668194220112789...2147130513336160133373
\n", - "

2 rows × 127 columns

\n", - "
" - ], - "text/plain": [ - " NAME B19001_001E \\\n", - "0 Block Group 1, Census Tract 1, Yukon-Koyukuk C... 187 \n", - "1 Block Group 2, Census Tract 1, Yukon-Koyukuk C... 336 \n", - "\n", - " B19001_002E B19001_003E B19001_004E B19001_005E B19001_006E \\\n", - "0 52 13 20 11 20 \n", - "1 68 19 42 20 11 \n", - "\n", - " B19001_007E B19001_008E B19001_009E ... B08201_002E B08201_003E \\\n", - "0 12 1 18 ... 119 40 \n", - "1 27 8 9 ... 214 71 \n", - "\n", - " B08201_004E B08201_005E B08201_006E B08202_001E B08202_002E \\\n", - "0 16 3 7 187 89 \n", - "1 30 5 13 336 160 \n", - "\n", - " B08202_003E B08202_004E B08202_005E \n", - "0 74 21 2 \n", - "1 133 37 3 \n", - "\n", - "[2 rows x 127 columns]" - ] - }, - "execution_count": 10, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "starter.h_acs.head(2)" ] }, { "cell_type": "code", - "execution_count": 11, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -684,57 +540,27 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 12, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "starter.c " ] }, { "cell_type": "code", - "execution_count": 13, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 13, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "c" ] }, { "cell_type": "code", - "execution_count": 14, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "['_get_fips_lookup', '_get_pums_relationship', '_query', '_read_csv', '_scale_and_merge', 'acsyear_files', 'base_url', 'block_group_and_tract_query', 'block_group_query', 'c', 'download_household_pums', 'download_population_pums', 'fips_df', 'fips_url', 'pums00_household_base_url', 'pums00_population_base_url', 'pums10_household_base_url', 'pums10_population_base_url', 'pums_cache', 'pums_household_state_base_url', 'pums_population_state_base_url', 'pums_relationship_df', 'pums_relationship_file_url', 'tract_query', 'tract_to_puma', 'try_fips_lookup']\n" - ] - } - ], + "outputs": [], "source": [ "# that has his own methods \n", "print([ m for m in dir(c) if not m.startswith('__')])" @@ -751,20 +577,9 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - ">" - ] - }, - "execution_count": 15, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "# we create and merge both tables with:\n", "c.block_group_and_tract_query" @@ -781,17 +596,9 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "['ALL', '_acs', 'acs', 'acs1', 'acs1dp', 'acs3', 'acs3dp', 'acs5', 'acs5dp', 'session', 'sf1', 'sf3']\n" - ] - } - ], + "outputs": [], "source": [ "# imported methods from census module\n", "print([ m for m in dir(c.c) if not m.startswith('__')])" @@ -806,7 +613,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -821,7 +628,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -832,110 +639,16 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
NAMEB11005_001EB11005_002EB11005_011Estatecountytract
0Census Tract 1, Yukon-Koyukuk Census Area, Alaska523.0140.0383.002290000100
1Census Tract 2, Yukon-Koyukuk Census Area, Alaska549.0155.0394.002290000200
2Census Tract 3, Yukon-Koyukuk Census Area, Alaska612.0251.0361.002290000300
3Census Tract 4, Yukon-Koyukuk Census Area, Alaska372.0151.0221.002290000400
\n", - "
" - ], - "text/plain": [ - " NAME B11005_001E \\\n", - "0 Census Tract 1, Yukon-Koyukuk Census Area, Alaska 523.0 \n", - "1 Census Tract 2, Yukon-Koyukuk Census Area, Alaska 549.0 \n", - "2 Census Tract 3, Yukon-Koyukuk Census Area, Alaska 612.0 \n", - "3 Census Tract 4, Yukon-Koyukuk Census Area, Alaska 372.0 \n", - "\n", - " B11005_002E B11005_011E state county tract \n", - "0 140.0 383.0 02 290 000100 \n", - "1 155.0 394.0 02 290 000200 \n", - "2 251.0 361.0 02 290 000300 \n", - "3 151.0 221.0 02 290 000400 " - ] - }, - "execution_count": 19, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "pd.DataFrame(tr)" ] }, { "cell_type": "code", - "execution_count": 20, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -946,173 +659,9 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
NAMEB11005_001EB11005_002EB11005_011Estatecountytractblock group
0Block Group 1, Census Tract 1, Yukon-Koyukuk C...187.058.0129.0022900001001
1Block Group 2, Census Tract 1, Yukon-Koyukuk C...336.082.0254.0022900001002
2Block Group 1, Census Tract 2, Yukon-Koyukuk C...208.057.0151.0022900002001
3Block Group 2, Census Tract 2, Yukon-Koyukuk C...341.098.0243.0022900002002
4Block Group 1, Census Tract 3, Yukon-Koyukuk C...234.0108.0126.0022900003001
5Block Group 2, Census Tract 3, Yukon-Koyukuk C...190.076.0114.0022900003002
6Block Group 3, Census Tract 3, Yukon-Koyukuk C...188.067.0121.0022900003003
7Block Group 1, Census Tract 4, Yukon-Koyukuk C...180.082.098.0022900004001
8Block Group 2, Census Tract 4, Yukon-Koyukuk C...192.069.0123.0022900004002
\n", - "
" - ], - "text/plain": [ - " NAME B11005_001E \\\n", - "0 Block Group 1, Census Tract 1, Yukon-Koyukuk C... 187.0 \n", - "1 Block Group 2, Census Tract 1, Yukon-Koyukuk C... 336.0 \n", - "2 Block Group 1, Census Tract 2, Yukon-Koyukuk C... 208.0 \n", - "3 Block Group 2, Census Tract 2, Yukon-Koyukuk C... 341.0 \n", - "4 Block Group 1, Census Tract 3, Yukon-Koyukuk C... 234.0 \n", - "5 Block Group 2, Census Tract 3, Yukon-Koyukuk C... 190.0 \n", - "6 Block Group 3, Census Tract 3, Yukon-Koyukuk C... 188.0 \n", - "7 Block Group 1, Census Tract 4, Yukon-Koyukuk C... 180.0 \n", - "8 Block Group 2, Census Tract 4, Yukon-Koyukuk C... 192.0 \n", - "\n", - " B11005_002E B11005_011E state county tract block group \n", - "0 58.0 129.0 02 290 000100 1 \n", - "1 82.0 254.0 02 290 000100 2 \n", - "2 57.0 151.0 02 290 000200 1 \n", - "3 98.0 243.0 02 290 000200 2 \n", - "4 108.0 126.0 02 290 000300 1 \n", - "5 76.0 114.0 02 290 000300 2 \n", - "6 67.0 121.0 02 290 000300 3 \n", - "7 82.0 98.0 02 290 000400 1 \n", - "8 69.0 123.0 02 290 000400 2 " - ] - }, - "execution_count": 21, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "pd.DataFrame(bg)" ] @@ -1126,163 +675,9 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
NAMEB08201_001EB08201_002EB08201_003EB08201_004EB08201_005EB08201_006E
0Block Group 1, Census Tract 1, Yukon-Koyukuk C...187119401637
1Block Group 2, Census Tract 1, Yukon-Koyukuk C...3362147130513
2Block Group 1, Census Tract 2, Yukon-Koyukuk C...2085173502111
3Block Group 2, Census Tract 2, Yukon-Koyukuk C...34183120833418
4Block Group 1, Census Tract 3, Yukon-Koyukuk C...234127583584
5Block Group 2, Census Tract 3, Yukon-Koyukuk C...190103472873
6Block Group 3, Census Tract 3, Yukon-Koyukuk C...188102462873
7Block Group 1, Census Tract 4, Yukon-Koyukuk C...18091463252
8Block Group 2, Census Tract 4, Yukon-Koyukuk C...19298503553
\n", - "
" - ], - "text/plain": [ - " NAME B08201_001E \\\n", - "0 Block Group 1, Census Tract 1, Yukon-Koyukuk C... 187 \n", - "1 Block Group 2, Census Tract 1, Yukon-Koyukuk C... 336 \n", - "2 Block Group 1, Census Tract 2, Yukon-Koyukuk C... 208 \n", - "3 Block Group 2, Census Tract 2, Yukon-Koyukuk C... 341 \n", - "4 Block Group 1, Census Tract 3, Yukon-Koyukuk C... 234 \n", - "5 Block Group 2, Census Tract 3, Yukon-Koyukuk C... 190 \n", - "6 Block Group 3, Census Tract 3, Yukon-Koyukuk C... 188 \n", - "7 Block Group 1, Census Tract 4, Yukon-Koyukuk C... 180 \n", - "8 Block Group 2, Census Tract 4, Yukon-Koyukuk C... 192 \n", - "\n", - " B08201_002E B08201_003E B08201_004E B08201_005E B08201_006E \n", - "0 119 40 16 3 7 \n", - "1 214 71 30 5 13 \n", - "2 51 73 50 21 11 \n", - "3 83 120 83 34 18 \n", - "4 127 58 35 8 4 \n", - "5 103 47 28 7 3 \n", - "6 102 46 28 7 3 \n", - "7 91 46 32 5 2 \n", - "8 98 50 35 5 3 " - ] - }, - "execution_count": 22, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "# tract variables\n", "starter.h_acs[['NAME']+vehicle_columns]" @@ -1297,7 +692,7 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -1313,104 +708,9 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
NAMEB11005_001EB11005_002EB11005_011Estatecountytractblock groupB08201_001EB08201_002EB08201_003EB08201_004EB08201_005EB08201_006E
0Block Group 1, Census Tract 1, Yukon-Koyukuk C...18758129022900001001187119401637
1Block Group 2, Census Tract 1, Yukon-Koyukuk C...336822540229000010023362147130513
\n", - "
" - ], - "text/plain": [ - " NAME B11005_001E \\\n", - "0 Block Group 1, Census Tract 1, Yukon-Koyukuk C... 187 \n", - "1 Block Group 2, Census Tract 1, Yukon-Koyukuk C... 336 \n", - "\n", - " B11005_002E B11005_011E state county tract block group B08201_001E \\\n", - "0 58 129 02 290 000100 1 187 \n", - "1 82 254 02 290 000100 2 336 \n", - "\n", - " B08201_002E B08201_003E B08201_004E B08201_005E B08201_006E \n", - "0 119 40 16 3 7 \n", - "1 214 71 30 5 13 " - ] - }, - "execution_count": 24, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "h_acs.head(2)" ] @@ -1431,7 +731,7 @@ }, { "cell_type": "code", - "execution_count": 25, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -1440,20 +740,9 @@ }, { "cell_type": "code", - "execution_count": 26, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 26, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "cat.categorize" ] @@ -1467,7 +756,7 @@ }, { "cell_type": "code", - "execution_count": 27, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -1482,166 +771,9 @@ }, { "cell_type": "code", - "execution_count": 28, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
cat_namehh_carshh_children
cat_valuenoneonetwo or morenoyes
statecountytractblock group
022900001001119402612958
2214714825482
000200151738215157
28312013524398
00030011275847126108
2103473811476
3102463812167
00040019146399882
298504312369
\n", - "
" - ], - "text/plain": [ - "cat_name hh_cars hh_children \n", - "cat_value none one two or more no yes\n", - "state county tract block group \n", - "02 290 000100 1 119 40 26 129 58\n", - " 2 214 71 48 254 82\n", - " 000200 1 51 73 82 151 57\n", - " 2 83 120 135 243 98\n", - " 000300 1 127 58 47 126 108\n", - " 2 103 47 38 114 76\n", - " 3 102 46 38 121 67\n", - " 000400 1 91 46 39 98 82\n", - " 2 98 50 43 123 69" - ] - }, - "execution_count": 28, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "h_acs_cat" ] @@ -1655,404 +787,9 @@ }, { "cell_type": "code", - "execution_count": 29, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
cat_namehh_age_of_headhh_carshh_childrenhh_income...hispanic_headseniorssf_detachedtenure_mover
cat_valuegt35-lt65gt65lt35noneonetwo or morenoyesgt100-lt150gt150...noyesnoyesnoyesown not recentown recentrent not recentrent recent
statecountytractblock group
022900001001122254011940261295860...187016225018713593112
221077492147148254823315...33152597720316222104658
000200112367185173821515782...2044138701519314744512
2229763683120135243985925...33922548744297240116921
00030011464345127584712610891...234018450123315094728
212144251034738114764116...1882143476184129132919
3112373910246381216780...188014741418413523318
0004001924939914639988237...180013149018012164211
2108463898504312369166...18841444871859786918
\n", - "

9 rows × 34 columns

\n", - "
" - ], - "text/plain": [ - "cat_name hh_age_of_head hh_cars \\\n", - "cat_value gt35-lt65 gt65 lt35 none one \n", - "state county tract block group \n", - "02 290 000100 1 122 25 40 119 40 \n", - " 2 210 77 49 214 71 \n", - " 000200 1 123 67 18 51 73 \n", - " 2 229 76 36 83 120 \n", - " 000300 1 146 43 45 127 58 \n", - " 2 121 44 25 103 47 \n", - " 3 112 37 39 102 46 \n", - " 000400 1 92 49 39 91 46 \n", - " 2 108 46 38 98 50 \n", - "\n", - "cat_name hh_children hh_income \\\n", - "cat_value two or more no yes gt100-lt150 \n", - "state county tract block group \n", - "02 290 000100 1 26 129 58 6 \n", - " 2 48 254 82 33 \n", - " 000200 1 82 151 57 8 \n", - " 2 135 243 98 59 \n", - " 000300 1 47 126 108 9 \n", - " 2 38 114 76 41 \n", - " 3 38 121 67 8 \n", - " 000400 1 39 98 82 3 \n", - " 2 43 123 69 16 \n", - "\n", - "cat_name ... hispanic_head seniors \\\n", - "cat_value gt150 ... no yes no yes \n", - "state county tract block group ... \n", - "02 290 000100 1 0 ... 187 0 162 25 \n", - " 2 15 ... 331 5 259 77 \n", - " 000200 1 2 ... 204 4 138 70 \n", - " 2 25 ... 339 2 254 87 \n", - " 000300 1 1 ... 234 0 184 50 \n", - " 2 16 ... 188 2 143 47 \n", - " 3 0 ... 188 0 147 41 \n", - " 000400 1 7 ... 180 0 131 49 \n", - " 2 6 ... 188 4 144 48 \n", - "\n", - "cat_name sf_detached tenure_mover \\\n", - "cat_value no yes own not recent own recent \n", - "state county tract block group \n", - "02 290 000100 1 0 187 135 9 \n", - " 2 20 316 222 10 \n", - " 000200 1 15 193 147 4 \n", - " 2 44 297 240 11 \n", - " 000300 1 1 233 150 9 \n", - " 2 6 184 129 13 \n", - " 3 4 184 135 2 \n", - " 000400 1 0 180 121 6 \n", - " 2 7 185 97 8 \n", - "\n", - "cat_name \n", - "cat_value rent not recent rent recent \n", - "state county tract block group \n", - "02 290 000100 1 31 12 \n", - " 2 46 58 \n", - " 000200 1 45 12 \n", - " 2 69 21 \n", - " 000300 1 47 28 \n", - " 2 29 19 \n", - " 3 33 18 \n", - " 000400 1 42 11 \n", - " 2 69 18 \n", - "\n", - "[9 rows x 34 columns]" - ] - }, - "execution_count": 29, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "# here the entire table built in starter2\n", "starter.h_acs_cat" @@ -2081,20 +818,9 @@ }, { "cell_type": "code", - "execution_count": 30, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - ">" - ] - }, - "execution_count": 30, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "c.tract_to_puma" ] @@ -2108,24 +834,9 @@ }, { "cell_type": "code", - "execution_count": 31, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "puma10 id for tract 000100 : 00400\n", - "puma00 id for tract 000100 : 00400\n", - "puma10 id for tract 000200 : 00400\n", - "puma00 id for tract 000200 : 00400\n", - "puma10 id for tract 000300 : 00400\n", - "puma00 id for tract 000300 : 00400\n", - "puma10 id for tract 000400 : 00400\n", - "puma00 id for tract 000400 : 00400\n" - ] - } - ], + "outputs": [], "source": [ "for tract in ['000100','000200','000300','000400']:\n", " print('puma10 id for tract {} : {}'.format(tract, c.tract_to_puma(state, county, tract)[0]))\n", @@ -2174,7 +885,7 @@ }, { "cell_type": "code", - "execution_count": 32, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -2185,280 +896,18 @@ }, { "cell_type": "code", - "execution_count": 33, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Downloading households pums from https://s3-us-west-1.amazonaws.com/synthpop-data2/\n", - "Reading PUMS00 from https://s3-us-west-1.amazonaws.com/synthpop-data2/\n" - ] - } - ], + "outputs": [], "source": [ "h_pums = c.download_household_pums(state, puma10, puma00, usecols=h_pums_cols)" ] }, { "cell_type": "code", - "execution_count": 34, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
serialnoRTpuma00puma10NPTYPEBLDTENVEHHINCPMVR18R65
02012000000643H-9400212.03.00.033360.01.00.00.0
22012000001889H-9400412.02.00.089420.07.00.02.0
32012000003083H-9400112.02.00.020800.07.00.00.0
42012000004753H-9400712.02.00.026300.06.01.00.0
52012000005450H-9400313.03.01.065300.01.01.00.0
..........................................
58572011001481195H400-9612.03.01.0165600.07.01.01.0
58582011001486432H400-9512.02.00.023900.05.01.00.0
58622011001495660H400-9312.02.02.029500.07.00.02.0
58652011001496296H400-9112.04.00.0900.07.00.00.0
58682011001498413H400-9412.03.01.019600.02.01.00.0
\n", - "

3625 rows × 13 columns

\n", - "
" - ], - "text/plain": [ - " serialno RT puma00 puma10 NP TYPE BLD TEN VEH HINCP MV \\\n", - "0 2012000000643 H -9 400 2 1 2.0 3.0 0.0 33360.0 1.0 \n", - "2 2012000001889 H -9 400 4 1 2.0 2.0 0.0 89420.0 7.0 \n", - "3 2012000003083 H -9 400 1 1 2.0 2.0 0.0 20800.0 7.0 \n", - "4 2012000004753 H -9 400 7 1 2.0 2.0 0.0 26300.0 6.0 \n", - "5 2012000005450 H -9 400 3 1 3.0 3.0 1.0 65300.0 1.0 \n", - "... ... .. ... ... .. ... ... ... ... ... ... \n", - "5857 2011001481195 H 400 -9 6 1 2.0 3.0 1.0 165600.0 7.0 \n", - "5858 2011001486432 H 400 -9 5 1 2.0 2.0 0.0 23900.0 5.0 \n", - "5862 2011001495660 H 400 -9 3 1 2.0 2.0 2.0 29500.0 7.0 \n", - "5865 2011001496296 H 400 -9 1 1 2.0 4.0 0.0 900.0 7.0 \n", - "5868 2011001498413 H 400 -9 4 1 2.0 3.0 1.0 19600.0 2.0 \n", - "\n", - " R18 R65 \n", - "0 0.0 0.0 \n", - "2 0.0 2.0 \n", - "3 0.0 0.0 \n", - "4 1.0 0.0 \n", - "5 1.0 0.0 \n", - "... ... ... \n", - "5857 1.0 1.0 \n", - "5858 1.0 0.0 \n", - "5862 0.0 2.0 \n", - "5865 0.0 0.0 \n", - "5868 1.0 0.0 \n", - "\n", - "[3625 rows x 13 columns]" - ] - }, - "execution_count": 34, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "h_pums" ] @@ -2479,20 +928,9 @@ }, { "cell_type": "code", - "execution_count": 35, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 35, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "cat.joint_distribution" ] @@ -2506,87 +944,9 @@ }, { "cell_type": "code", - "execution_count": 36, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
cat_id
hh_carshh_children
noneno0
yes1
oneno2
yes3
two or moreno4
yes5
\n", - "
" - ], - "text/plain": [ - " cat_id\n", - "hh_cars hh_children \n", - "none no 0\n", - " yes 1\n", - "one no 2\n", - " yes 3\n", - "two or more no 4\n", - " yes 5" - ] - }, - "execution_count": 36, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "cat.category_combinations(h_acs_cat.columns)" ] @@ -2600,7 +960,7 @@ }, { "cell_type": "code", - "execution_count": 37, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -2620,7 +980,7 @@ }, { "cell_type": "code", - "execution_count": 38, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -2642,95 +1002,9 @@ }, { "cell_type": "code", - "execution_count": 39, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
cat_idfrequency
hh_carshh_children
noneno0843
yes1919
oneno2573
yes3431
two or moreno4491
yes5368
\n", - "
" - ], - "text/plain": [ - " cat_id frequency\n", - "hh_cars hh_children \n", - "none no 0 843\n", - " yes 1 919\n", - "one no 2 573\n", - " yes 3 431\n", - "two or more no 4 491\n", - " yes 5 368" - ] - }, - "execution_count": 39, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "jd_households" ] @@ -2746,298 +1020,9 @@ }, { "cell_type": "code", - "execution_count": 40, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
serialnoRTpuma00puma10NPTYPEBLDTENVEHHINCPMVR18R65hh_carshh_childrencat_id
02012000000643H-9400212.03.00.033360.01.00.00.0noneno0
22012000001889H-9400412.02.00.089420.07.00.02.0noneno0
32012000003083H-9400112.02.00.020800.07.00.00.0noneno0
152012000017291H-9400412.02.00.054800.05.00.00.0noneno0
312012000041419H-9400212.02.00.033300.07.00.01.0noneno0
...................................................
57622011001370081H400-9112.02.06.0300300.05.00.00.0two or moreno4
57712011001380825H400-9212.04.02.0173600.01.00.00.0two or moreno4
58352011001457691H400-9211.03.02.097400.03.00.00.0two or moreno4
58432011001464975H400-9412.01.02.08650.05.00.00.0two or moreno4
58622011001495660H400-9312.02.02.029500.07.00.02.0two or moreno4
\n", - "

3625 rows × 16 columns

\n", - "
" - ], - "text/plain": [ - " serialno RT puma00 puma10 NP TYPE BLD TEN VEH HINCP MV \\\n", - "0 2012000000643 H -9 400 2 1 2.0 3.0 0.0 33360.0 1.0 \n", - "2 2012000001889 H -9 400 4 1 2.0 2.0 0.0 89420.0 7.0 \n", - "3 2012000003083 H -9 400 1 1 2.0 2.0 0.0 20800.0 7.0 \n", - "15 2012000017291 H -9 400 4 1 2.0 2.0 0.0 54800.0 5.0 \n", - "31 2012000041419 H -9 400 2 1 2.0 2.0 0.0 33300.0 7.0 \n", - "... ... .. ... ... .. ... ... ... ... ... ... \n", - "5762 2011001370081 H 400 -9 1 1 2.0 2.0 6.0 300300.0 5.0 \n", - "5771 2011001380825 H 400 -9 2 1 2.0 4.0 2.0 173600.0 1.0 \n", - "5835 2011001457691 H 400 -9 2 1 1.0 3.0 2.0 97400.0 3.0 \n", - "5843 2011001464975 H 400 -9 4 1 2.0 1.0 2.0 8650.0 5.0 \n", - "5862 2011001495660 H 400 -9 3 1 2.0 2.0 2.0 29500.0 7.0 \n", - "\n", - " R18 R65 hh_cars hh_children cat_id \n", - "0 0.0 0.0 none no 0 \n", - "2 0.0 2.0 none no 0 \n", - "3 0.0 0.0 none no 0 \n", - "15 0.0 0.0 none no 0 \n", - "31 0.0 1.0 none no 0 \n", - "... ... ... ... ... ... \n", - "5762 0.0 0.0 two or more no 4 \n", - "5771 0.0 0.0 two or more no 4 \n", - "5835 0.0 0.0 two or more no 4 \n", - "5843 0.0 0.0 two or more no 4 \n", - "5862 0.0 2.0 two or more no 4 \n", - "\n", - "[3625 rows x 16 columns]" - ] - }, - "execution_count": 40, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "h_pums" ] @@ -3069,24 +1054,9 @@ }, { "cell_type": "code", - "execution_count": 41, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "state 02\n", - "county 290\n", - "tract 000100\n", - "block group 1\n", - "dtype: object" - ] - }, - "execution_count": 41, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "#...for a group of available geographies inside a county/state pair\n", "list(starter.get_available_geography_ids())[0]" @@ -3094,7 +1064,7 @@ }, { "cell_type": "code", - "execution_count": 42, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -3103,7 +1073,7 @@ }, { "cell_type": "code", - "execution_count": 43, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -3120,55 +1090,9 @@ }, { "cell_type": "code", - "execution_count": 44, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "cat_name cat_value \n", - "hh_age_of_head gt35-lt65 108\n", - " gt65 46\n", - " lt35 38\n", - "hh_cars none 98\n", - " one 50\n", - " two or more 43\n", - "hh_children no 123\n", - " yes 69\n", - "hh_income gt100-lt150 16\n", - " gt150 6\n", - " gt30-lt60 32\n", - " gt60-lt100 81\n", - " lt30 57\n", - "hh_race_of_head asian 0\n", - " black 2\n", - " other 108\n", - " white 82\n", - "hh_size four or more 36\n", - " one 61\n", - " three 44\n", - " two 51\n", - "hh_workers none 69\n", - " one 77\n", - " two or more 45\n", - "hispanic_head no 188\n", - " yes 4\n", - "seniors no 144\n", - " yes 48\n", - "sf_detached no 7\n", - " yes 185\n", - "tenure_mover own not recent 97\n", - " own recent 8\n", - " rent not recent 69\n", - " rent recent 18\n", - "Name: (02, 290, 000400, 2), dtype: int64" - ] - }, - "execution_count": 44, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "# This is the marginal table we stored for the last census tract (400)\n", "h_marg" @@ -3183,166 +1107,9 @@ }, { "cell_type": "code", - "execution_count": 45, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
cat_namehh_carshh_children
cat_valuenoneonetwo or morenoyes
statecountytractblock group
022900001001119402612958
2214714825482
000200151738215157
28312013524398
00030011275847126108
2103473811476
3102463812167
00040019146399882
298504312369
\n", - "
" - ], - "text/plain": [ - "cat_name hh_cars hh_children \n", - "cat_value none one two or more no yes\n", - "state county tract block group \n", - "02 290 000100 1 119 40 26 129 58\n", - " 2 214 71 48 254 82\n", - " 000200 1 51 73 82 151 57\n", - " 2 83 120 135 243 98\n", - " 000300 1 127 58 47 126 108\n", - " 2 103 47 38 114 76\n", - " 3 102 46 38 121 67\n", - " 000400 1 91 46 39 98 82\n", - " 2 98 50 43 123 69" - ] - }, - "execution_count": 45, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "# can check these totals in our acs subject table...\n", "h_acs_cat" @@ -3350,7 +1117,7 @@ }, { "cell_type": "code", - "execution_count": 46, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -3360,26 +1127,9 @@ }, { "cell_type": "code", - "execution_count": 47, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "cat_name cat_value \n", - "hh_cars none 91\n", - " one 46\n", - " two or more 39\n", - "hh_children no 98\n", - " yes 82\n", - "Name: (02, 290, 000400, 1), dtype: int64" - ] - }, - "execution_count": 47, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "hh_marginals_tract_400_block_gp_1" ] @@ -3407,7 +1157,7 @@ }, { "cell_type": "code", - "execution_count": 48, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -3416,7 +1166,7 @@ }, { "cell_type": "code", - "execution_count": 49, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -3425,27 +1175,9 @@ }, { "cell_type": "code", - "execution_count": 50, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "hh_cars hh_children\n", - "none no 46.529753\n", - " yes 46.538428\n", - "one no 27.835805\n", - " yes 19.209650\n", - "two or more no 23.634442\n", - " yes 16.251921\n", - "dtype: float64" - ] - }, - "execution_count": 50, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "# this is our contraints table\n", "h_constraint" @@ -3453,20 +1185,9 @@ }, { "cell_type": "code", - "execution_count": 51, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "4" - ] - }, - "execution_count": 51, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "# this is the number of iterations performed to achieve the constraint values\n", "_" @@ -3481,7 +1202,7 @@ }, { "cell_type": "code", - "execution_count": 52, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -3490,24 +1211,9 @@ }, { "cell_type": "code", - "execution_count": 53, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "cat_name cat_value \n", - "hh_cars none 91\n", - " one 46\n", - " two or more 39\n", - "Name: (02, 290, 000400, 1), dtype: int64" - ] - }, - "execution_count": 53, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "bg_targets" ] @@ -3521,89 +1227,18 @@ }, { "cell_type": "code", - "execution_count": 54, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
cat_idfrequency
hh_carshh_children
noneno0843
yes1919
\n", - "
" - ], - "text/plain": [ - " cat_id frequency\n", - "hh_cars hh_children \n", - "none no 0 843\n", - " yes 1 919" - ] - }, - "execution_count": 54, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "jd_households[:2]" ] }, { "cell_type": "code", - "execution_count": 55, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "1762" - ] - }, - "execution_count": 55, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "jd_households['frequency'][:2].sum()" ] @@ -3619,31 +1254,9 @@ }, { "cell_type": "code", - "execution_count": 56, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Block group target value: 91\n", - "Total value of the combined category is: 1762\n", - "Proportion of each category in the combined variables total: 0.051645856980703744\n", - "New Block group target value: 4.69977298524404\n", - "*********************************************************************************\n", - "Block group target value: 46\n", - "Total value of the combined category is: 1004\n", - "Proportion of each category in the combined variables total: 0.045816733067729085\n", - "New Block group target value: 2.1075697211155378\n", - "*********************************************************************************\n", - "Block group target value: 39\n", - "Total value of the combined category is: 859\n", - "Proportion of each category in the combined variables total: 0.04540162980209546\n", - "New Block group target value: 1.7706635622817228\n", - "*********************************************************************************\n" - ] - } - ], + "outputs": [], "source": [ "sub_category_idx_0 = 0\n", "sub_category_idx_1 = 2\n", @@ -3668,25 +1281,9 @@ }, { "cell_type": "code", - "execution_count": 57, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "array([[ 0, 843],\n", - " [ 1, 919],\n", - " [ 2, 573],\n", - " [ 3, 431],\n", - " [ 4, 491],\n", - " [ 5, 368]])" - ] - }, - "execution_count": 57, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "jd_households.values" ] @@ -3707,7 +1304,7 @@ }, { "cell_type": "code", - "execution_count": 58, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -3716,7 +1313,7 @@ }, { "cell_type": "code", - "execution_count": 59, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -3728,7 +1325,7 @@ }, { "cell_type": "code", - "execution_count": 60, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -3741,22 +1338,9 @@ }, { "cell_type": "code", - "execution_count": 61, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "array([[0. , 4.69977299],\n", - " [1. , 2.10756972],\n", - " [2. , 1.77066356]])" - ] - }, - "execution_count": 61, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "next_constraints" ] @@ -3770,7 +1354,7 @@ }, { "cell_type": "code", - "execution_count": 62, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -3779,37 +1363,18 @@ }, { "cell_type": "code", - "execution_count": 63, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "2338.0" - ] - }, - "execution_count": 63, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "np.abs(current_constraints, next_constraints).sum()" ] }, { "cell_type": "code", - "execution_count": 64, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Recalculate constraints table\n" - ] - } - ], + "outputs": [], "source": [ "if np.abs(current_constraints, next_constraints).sum()>tolerance:\n", " print('Recalculate constraints table')" @@ -3824,26 +1389,9 @@ }, { "cell_type": "code", - "execution_count": 65, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "cat_name cat_value \n", - "hh_cars none 91\n", - " one 46\n", - " two or more 39\n", - "hh_children no 98\n", - " yes 82\n", - "Name: (02, 290, 000400, 1), dtype: int64" - ] - }, - "execution_count": 65, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "# ... our marginals table with total values for the block group\n", "hh_marginals_tract_400_block_gp_1" @@ -3851,32 +1399,24 @@ }, { "cell_type": "code", - "execution_count": 66, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "hh_cars hh_children\n", - "none no 46.529753\n", - " yes 46.538428\n", - "one no 27.835805\n", - " yes 19.209650\n", - "two or more no 23.634442\n", - " yes 16.251921\n", - "dtype: float64" - ] - }, - "execution_count": 66, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "# updated with new totals.\n", "h_constraint" ] }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# that will be used to update joint distributions frequencies\n", + "jd_households" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -3892,12 +1432,10 @@ ] }, { - "cell_type": "code", - "execution_count": 106, + "cell_type": "markdown", "metadata": {}, - "outputs": [], "source": [ - "from synthpop.ipu.ipu import household_weights" + "![ipu](img/ipf_ipu.png)" ] }, { @@ -3905,11 +1443,13 @@ "execution_count": null, "metadata": {}, "outputs": [], - "source": [] + "source": [ + "from synthpop.ipu.ipu import household_weights" + ] }, { "cell_type": "code", - "execution_count": 67, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -3918,27 +1458,9 @@ }, { "cell_type": "code", - "execution_count": 68, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "cat_id\n", - "0 46.529753\n", - "1 46.538428\n", - "2 27.835805\n", - "3 19.209650\n", - "4 23.634442\n", - "5 16.251921\n", - "dtype: float64" - ] - }, - "execution_count": 68, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "h_constraint" ] @@ -3952,7 +1474,7 @@ }, { "cell_type": "code", - "execution_count": 69, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -3961,176 +1483,16 @@ }, { "cell_type": "code", - "execution_count": 70, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
serialnoRTpuma00puma10NPTYPEBLDTENVEHHINCPMVR18R65hh_carshh_childrencat_id
02012000000643H-9400212.03.00.033360.01.00.00.0noneno0
22012000001889H-9400412.02.00.089420.07.00.02.0noneno0
32012000003083H-9400112.02.00.020800.07.00.00.0noneno0
152012000017291H-9400412.02.00.054800.05.00.00.0noneno0
312012000041419H-9400212.02.00.033300.07.00.01.0noneno0
\n", - "
" - ], - "text/plain": [ - " serialno RT puma00 puma10 NP TYPE BLD TEN VEH HINCP MV \\\n", - "0 2012000000643 H -9 400 2 1 2.0 3.0 0.0 33360.0 1.0 \n", - "2 2012000001889 H -9 400 4 1 2.0 2.0 0.0 89420.0 7.0 \n", - "3 2012000003083 H -9 400 1 1 2.0 2.0 0.0 20800.0 7.0 \n", - "15 2012000017291 H -9 400 4 1 2.0 2.0 0.0 54800.0 5.0 \n", - "31 2012000041419 H -9 400 2 1 2.0 2.0 0.0 33300.0 7.0 \n", - "\n", - " R18 R65 hh_cars hh_children cat_id \n", - "0 0.0 0.0 none no 0 \n", - "2 0.0 2.0 none no 0 \n", - "3 0.0 0.0 none no 0 \n", - "15 0.0 0.0 none no 0 \n", - "31 0.0 1.0 none no 0 " - ] - }, - "execution_count": 70, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "households_sample_df.head()" ] }, { "cell_type": "code", - "execution_count": 71, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -4139,7 +1501,7 @@ }, { "cell_type": "code", - "execution_count": 72, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -4148,7 +1510,7 @@ }, { "cell_type": "code", - "execution_count": 73, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -4157,7 +1519,7 @@ }, { "cell_type": "code", - "execution_count": 74, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -4166,198 +1528,109 @@ }, { "cell_type": "code", - "execution_count": 75, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
cat_id012345
hh_id
01.00.00.00.00.00.0
21.00.00.00.00.00.0
31.00.00.00.00.00.0
40.01.00.00.00.00.0
50.00.00.01.00.00.0
\n", - "
" - ], - "text/plain": [ - "cat_id 0 1 2 3 4 5\n", - "hh_id \n", - "0 1.0 0.0 0.0 0.0 0.0 0.0\n", - "2 1.0 0.0 0.0 0.0 0.0 0.0\n", - "3 1.0 0.0 0.0 0.0 0.0 0.0\n", - "4 0.0 1.0 0.0 0.0 0.0 0.0\n", - "5 0.0 0.0 0.0 1.0 0.0 0.0" - ] - }, - "execution_count": 75, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "h_freq_table.head()" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Togheter, frequency tables and constraints will be used for weights matrix and fit quality:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "best_weights, fit_quality, iterations = household_weights(h_freq_table,\n", + " None,\n", + " h_constraint,\n", + " None)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from synthpop.ipu.ipu import _FrequencyAndConstraints" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "freq_wrap = _FrequencyAndConstraints(h_freq_table, h_constraint)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This wrapper returns every `cat_id` column with non zero values:\n", + "\n", + "* `0` represents households with no car and no children \n", + "* `1` represents households with no car and children \n", + "* `2` represents households with one car and no children\n", + "* `3` represents households with one car and children\n", + "* `4` represents households with two or more cars and no children\n", + "* `5` represents households with two or more cars and children\n", + "\n", + "The wrapper returns each variables combination (from 0 to 5) inside a tuple with:\n", + "\n", + "1) `cat_id` value\n", + "\n", + "2) a `weights matrix`\n", + "\n", + "3) the new target value (the `constraint` or maximum value that the combination can reach within the block group) we built in the `ipf`.\n", + "\n", + "4) the index of non zero column values " + ] + }, { "cell_type": "code", - "execution_count": 107, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ - "best_weights, fit_quality, iterations = household_weights(h_freq_table,\n", - " None,\n", - " h_constraint,\n", - " None)" + "# here the information for all the combinations\n", + "freq_wrap.iter_columns()" ] }, { "cell_type": "code", - "execution_count": 108, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "hh_id\n", - "0 0.055195\n", - "2 0.055195\n", - "3 0.055195\n", - "4 0.050640\n", - "5 0.044570\n", - " ... \n", - "5857 0.044570\n", - "5858 0.050640\n", - "5862 0.048135\n", - "5865 0.055195\n", - "5868 0.044570\n", - "Length: 3625, dtype: float64" - ] - }, - "execution_count": 108, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ - "best_weights" + "# and here, we can see for category \"0\" that non zero values are...\n", + "freq_wrap.get_column(0)" ] }, { "cell_type": "code", - "execution_count": 109, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "1.636802750002612e-16" - ] - }, - "execution_count": 109, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ - "fit_quality" + "#... in the index 0, 1, 2, 7, (...)\n", + "h_freq_table[0][0:8]" ] }, { - "cell_type": "code", - "execution_count": 110, + "cell_type": "markdown", "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "2" - ] - }, - "execution_count": 110, - "metadata": {}, - "output_type": "execute_result" - } - ], "source": [ - "iterations" + "With this wrapper, we build the fit quality od each `cat_id`" ] }, { @@ -4365,810 +1638,88 @@ "execution_count": null, "metadata": {}, "outputs": [], - "source": [] + "source": [ + "from synthpop.ipu.ipu import _average_fit_quality\n", + "from synthpop.ipu.ipu import _fit_quality" + ] }, { "cell_type": "code", - "execution_count": 111, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ + "# weights matrix\n", "weights = np.ones(len(h_freq_table), dtype='float')\n", - "best_weights = weights.copy()" + "\n", + "# column (this is the non-zero elements of the \"0\" cat_id column of the frequency table)\n", + "cat_id_0_column = [e for e in freq_wrap.get_column(0)][1]\n", + "\n", + "# nz (this is the idx of the frequency table where non zero values are stored)\n", + "cat_id_0_nz = [e for e in freq_wrap.get_column(0)][3]" ] }, { "cell_type": "code", - "execution_count": 113, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ - "from synthpop.ipu.ipu import _FrequencyAndConstraints" + "# the non zero values should have the same length when filtering the weights matrix\n", + "len(cat_id_0_column) == len(weights[cat_id_0_nz])" ] }, { "cell_type": "code", - "execution_count": 116, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ - "freq_wrap = _FrequencyAndConstraints(h_freq_table, h_constraint)" + "# the new target value for the block group\n", + "constraint = [e for e in freq_wrap.get_column(0)][2]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# this is the \"fit quality\" value for cat_id \"0\"\n", + "_fit_quality(cat_id_0_column, weights[cat_id_0_nz], constraint)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "This wrapper returns every `cat_id` column with non zero values:\n", - "\n", - "* `0` represents households with no car and no children \n", - "* `1` represents households with no car and children \n", - "* `2` represents households with one car and no children\n", - "* `3` represents households with one car and children\n", - "* `4` represents households with two or more cars and no children\n", - "* `5` represents households with two or more cars and children\n", - "\n", - "The wrapper returns each variables combination (from 0 to 5) with a weights matrix, the new target value we built in the `ipf` and the index of non zero columns: " + "This value is the result of multiplying the non-zero values by the weights matrix, which returns the total frequency of the category within the PUMA: " ] }, { "cell_type": "code", - "execution_count": 121, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[(0,\n", - " array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.]),\n", - " 46.529753144154704,\n", - " array([ 0, 1, 2, 7, 16, 18, 20, 27, 32, 34, 38,\n", - " 41, 47, 58, 60, 74, 84, 86, 87, 88, 90, 95,\n", - " 97, 99, 106, 107, 108, 115, 116, 118, 121, 122, 130,\n", - " 131, 135, 138, 140, 159, 163, 165, 169, 175, 182, 190,\n", - " 192, 205, 207, 211, 212, 214, 215, 221, 223, 226, 227,\n", - " 228, 229, 232, 235, 240, 242, 256, 261, 268, 270, 279,\n", - " 280, 281, 282, 283, 285, 287, 291, 295, 297, 298, 299,\n", - " 300, 308, 309, 310, 311, 315, 320, 324, 331, 332, 336,\n", - " 338, 345, 356, 361, 363, 366, 367, 368, 372, 380, 383,\n", - " 388, 393, 400, 403, 406, 408, 418, 419, 430, 432, 433,\n", - " 434, 449, 450, 465, 466, 471, 472, 473, 483, 486, 499,\n", - " 504, 513, 514, 519, 537, 538, 540, 545, 546, 548, 552,\n", - " 553, 559, 565, 573, 579, 580, 583, 585, 589, 590, 597,\n", - " 598, 609, 613, 622, 624, 629, 632, 635, 636, 637, 638,\n", - " 641, 642, 646, 649, 650, 660, 661, 669, 672, 673, 684,\n", - " 687, 692, 697, 698, 706, 713, 716, 725, 727, 737, 738,\n", - " 739, 741, 747, 751, 754, 761, 762, 768, 797, 804, 805,\n", - " 809, 814, 815, 820, 822, 824, 825, 826, 837, 839, 840,\n", - " 842, 847, 855, 863, 866, 868, 872, 876, 887, 891, 901,\n", - " 905, 911, 916, 917, 923, 937, 939, 942, 945, 946, 952,\n", - " 960, 967, 969, 970, 973, 974, 975, 978, 984, 989, 990,\n", - " 993, 997, 999, 1000, 1005, 1006, 1009, 1011, 1015, 1021, 1022,\n", - " 1024, 1031, 1037, 1040, 1043, 1044, 1057, 1059, 1062, 1063, 1071,\n", - " 1072, 1073, 1079, 1083, 1090, 1093, 1094, 1096, 1097, 1101, 1106,\n", - " 1107, 1108, 1114, 1118, 1124, 1130, 1137, 1138, 1140, 1143, 1144,\n", - " 1161, 1171, 1175, 1178, 1180, 1186, 1187, 1188, 1192, 1196, 1197,\n", - " 1204, 1226, 1247, 1252, 1253, 1254, 1256, 1259, 1261, 1263, 1267,\n", - " 1271, 1279, 1285, 1292, 1295, 1302, 1305, 1308, 1317, 1319, 1321,\n", - " 1324, 1331, 1333, 1335, 1354, 1355, 1357, 1358, 1361, 1362, 1366,\n", - " 1367, 1373, 1382, 1395, 1396, 1397, 1406, 1407, 1408, 1409, 1415,\n", - " 1421, 1425, 1426, 1427, 1429, 1434, 1444, 1445, 1452, 1456, 1460,\n", - " 1461, 1466, 1474, 1480, 1481, 1482, 1490, 1491, 1493, 1501, 1509,\n", - " 1521, 1528, 1545, 1552, 1566, 1567, 1570, 1576, 1577, 1580, 1582,\n", - " 1594, 1603, 1605, 1618, 1619, 1627, 1628, 1643, 1645, 1650, 1653,\n", - " 1654, 1655, 1657, 1660, 1661, 1662, 1664, 1674, 1679, 1688, 1691,\n", - " 1692, 1701, 1704, 1705, 1709, 1710, 1711, 1712, 1713, 1715, 1729,\n", - " 1730, 1731, 1738, 1739, 1741, 1746, 1751, 1766, 1770, 1779, 1783,\n", - " 1785, 1787, 1800, 1802, 1811, 1816, 1820, 1821, 1824, 1829, 1833,\n", - " 1843, 1848, 1850, 1851, 1856, 1861, 1865, 1866, 1867, 1870, 1874,\n", - " 1875, 1878, 1883, 1887, 1890, 1891, 1893, 1897, 1903, 1904, 1905,\n", - " 1907, 1917, 1918, 1920, 1923, 1924, 1932, 1934, 1937, 1947, 1953,\n", - " 1957, 1958, 1962, 1965, 1971, 1972, 1975, 1976, 1979, 1980, 1998,\n", - " 2000, 2003, 2008, 2013, 2021, 2025, 2028, 2032, 2034, 2036, 2041,\n", - " 2048, 2049, 2056, 2061, 2064, 2068, 2070, 2076, 2080, 2086, 2090,\n", - " 2093, 2096, 2102, 2112, 2120, 2124, 2131, 2132, 2133, 2138, 2144,\n", - " 2146, 2159, 2165, 2167, 2173, 2174, 2183, 2184, 2189, 2198, 2200,\n", - " 2203, 2204, 2210, 2213, 2219, 2220, 2228, 2233, 2234, 2240, 2241,\n", - " 2251, 2252, 2255, 2260, 2264, 2265, 2267, 2273, 2280, 2283, 2284,\n", - " 2285, 2286, 2289, 2291, 2293, 2294, 2295, 2297, 2309, 2313, 2314,\n", - " 2317, 2321, 2331, 2335, 2344, 2350, 2352, 2364, 2369, 2370, 2371,\n", - " 2380, 2393, 2396, 2402, 2403, 2404, 2411, 2412, 2415, 2423, 2435,\n", - " 2445, 2447, 2450, 2453, 2466, 2469, 2476, 2481, 2491, 2495, 2507,\n", - " 2513, 2514, 2518, 2519, 2527, 2530, 2532, 2535, 2536, 2539, 2542,\n", - " 2545, 2546, 2547, 2559, 2562, 2565, 2577, 2579, 2584, 2588, 2593,\n", - " 2594, 2596, 2598, 2603, 2604, 2610, 2612, 2615, 2621, 2622, 2623,\n", - " 2631, 2638, 2642, 2646, 2647, 2654, 2659, 2660, 2661, 2662, 2667,\n", - " 2671, 2677, 2684, 2686, 2688, 2689, 2692, 2694, 2701, 2702, 2703,\n", - " 2705, 2706, 2712, 2714, 2715, 2717, 2719, 2724, 2728, 2729, 2735,\n", - " 2739, 2742, 2744, 2748, 2750, 2755, 2757, 2768, 2770, 2773, 2774,\n", - " 2776, 2777, 2778, 2779, 2780, 2785, 2790, 2791, 2792, 2802, 2803,\n", - " 2806, 2812, 2818, 2824, 2828, 2829, 2831, 2848, 2849, 2857, 2858,\n", - " 2861, 2864, 2872, 2874, 2877, 2882, 2884, 2885, 2890, 2898, 2900,\n", - " 2902, 2906, 2911, 2913, 2922, 2926, 2934, 2935, 2943, 2953, 2955,\n", - " 2964, 2967, 2969, 2972, 2973, 2981, 2983, 2984, 2985, 2988, 2990,\n", - " 2996, 2997, 3002, 3009, 3010, 3012, 3024, 3025, 3030, 3035, 3036,\n", - " 3043, 3045, 3047, 3052, 3053, 3055, 3062, 3069, 3072, 3077, 3079,\n", - " 3080, 3084, 3089, 3095, 3098, 3116, 3118, 3124, 3128, 3138, 3145,\n", - " 3148, 3166, 3168, 3173, 3174, 3178, 3185, 3193, 3205, 3208, 3214,\n", - " 3218, 3232, 3237, 3240, 3247, 3256, 3259, 3262, 3263, 3266, 3267,\n", - " 3270, 3273, 3287, 3294, 3296, 3301, 3302, 3311, 3316, 3320, 3336,\n", - " 3341, 3345, 3353, 3356, 3357, 3363, 3365, 3366, 3367, 3369, 3371,\n", - " 3376, 3377, 3380, 3390, 3391, 3393, 3397, 3399, 3401, 3404, 3406,\n", - " 3410, 3415, 3419, 3421, 3424, 3429, 3431, 3432, 3443, 3444, 3457,\n", - " 3458, 3459, 3462, 3466, 3468, 3470, 3471, 3472, 3473, 3478, 3488,\n", - " 3490, 3494, 3497, 3499, 3503, 3505, 3520, 3532, 3544, 3546, 3547,\n", - " 3548, 3550, 3551, 3556, 3557, 3562, 3567, 3570, 3576, 3578, 3581,\n", - " 3582, 3596, 3611, 3616, 3617, 3618, 3623])),\n", - " (1,\n", - " array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1.]),\n", - " 46.538428452649654,\n", - " array([ 3, 6, 8, 9, 21, 28, 29, 31, 33, 43, 48,\n", - " 52, 53, 55, 56, 57, 64, 69, 70, 73, 80, 83,\n", - " 93, 96, 101, 102, 103, 111, 114, 117, 120, 126, 127,\n", - " 128, 133, 134, 136, 137, 145, 148, 157, 160, 161, 164,\n", - " 170, 172, 173, 177, 183, 188, 189, 193, 198, 199, 201,\n", - " 202, 204, 206, 216, 230, 241, 247, 249, 255, 260, 265,\n", - " 267, 275, 276, 286, 289, 292, 296, 302, 304, 313, 318,\n", - " 323, 327, 334, 335, 340, 343, 351, 370, 373, 374, 381,\n", - " 386, 392, 398, 399, 404, 405, 407, 410, 412, 415, 420,\n", - " 424, 435, 437, 442, 443, 446, 451, 452, 454, 455, 460,\n", - " 462, 470, 474, 476, 479, 484, 485, 489, 490, 497, 502,\n", - " 503, 505, 508, 512, 516, 522, 530, 531, 532, 534, 539,\n", - " 542, 554, 563, 564, 581, 584, 586, 592, 595, 599, 600,\n", - " 604, 614, 619, 621, 630, 631, 633, 647, 648, 651, 653,\n", - " 654, 657, 659, 675, 676, 678, 685, 690, 695, 701, 702,\n", - " 704, 705, 707, 708, 709, 712, 714, 715, 720, 721, 728,\n", - " 731, 735, 736, 742, 743, 744, 746, 750, 756, 757, 758,\n", - " 759, 765, 773, 778, 779, 783, 786, 787, 791, 802, 806,\n", - " 808, 813, 817, 819, 821, 823, 829, 831, 833, 834, 838,\n", - " 846, 851, 853, 857, 859, 861, 867, 873, 878, 883, 888,\n", - " 890, 893, 894, 899, 907, 908, 910, 918, 922, 924, 925,\n", - " 927, 929, 930, 931, 932, 934, 941, 947, 950, 955, 965,\n", - " 968, 971, 976, 982, 995, 998, 1001, 1016, 1017, 1018, 1026,\n", - " 1030, 1032, 1035, 1036, 1046, 1060, 1066, 1067, 1070, 1075, 1077,\n", - " 1082, 1100, 1104, 1110, 1112, 1115, 1117, 1120, 1129, 1131, 1132,\n", - " 1133, 1135, 1139, 1147, 1148, 1151, 1152, 1157, 1160, 1165, 1169,\n", - " 1183, 1189, 1194, 1202, 1210, 1213, 1214, 1220, 1224, 1227, 1233,\n", - " 1238, 1243, 1244, 1249, 1258, 1275, 1277, 1280, 1282, 1283, 1284,\n", - " 1287, 1289, 1293, 1301, 1307, 1310, 1313, 1315, 1320, 1329, 1330,\n", - " 1337, 1338, 1340, 1344, 1346, 1352, 1356, 1364, 1365, 1372, 1379,\n", - " 1384, 1394, 1402, 1405, 1412, 1414, 1418, 1419, 1424, 1428, 1431,\n", - " 1436, 1440, 1446, 1453, 1454, 1464, 1468, 1469, 1471, 1473, 1475,\n", - " 1478, 1486, 1487, 1496, 1497, 1498, 1500, 1503, 1507, 1511, 1512,\n", - " 1513, 1518, 1520, 1524, 1531, 1532, 1535, 1539, 1540, 1542, 1543,\n", - " 1553, 1557, 1560, 1563, 1568, 1578, 1581, 1584, 1585, 1587, 1589,\n", - " 1590, 1591, 1595, 1599, 1601, 1604, 1606, 1610, 1614, 1615, 1616,\n", - " 1620, 1631, 1640, 1648, 1656, 1658, 1663, 1665, 1668, 1671, 1680,\n", - " 1685, 1687, 1690, 1702, 1706, 1707, 1725, 1726, 1728, 1733, 1734,\n", - " 1736, 1740, 1750, 1754, 1755, 1760, 1762, 1769, 1773, 1775, 1778,\n", - " 1780, 1781, 1782, 1784, 1788, 1789, 1791, 1794, 1797, 1798, 1806,\n", - " 1810, 1815, 1818, 1822, 1827, 1831, 1832, 1834, 1836, 1838, 1855,\n", - " 1857, 1858, 1859, 1860, 1862, 1863, 1864, 1869, 1876, 1880, 1886,\n", - " 1888, 1894, 1899, 1901, 1909, 1913, 1915, 1919, 1921, 1925, 1926,\n", - " 1929, 1936, 1938, 1940, 1941, 1943, 1952, 1955, 1956, 1960, 1963,\n", - " 1966, 1970, 1973, 1981, 1984, 1991, 1999, 2001, 2002, 2004, 2006,\n", - " 2009, 2012, 2015, 2016, 2017, 2022, 2027, 2031, 2035, 2038, 2039,\n", - " 2047, 2051, 2055, 2063, 2065, 2067, 2071, 2077, 2079, 2083, 2084,\n", - " 2088, 2092, 2104, 2114, 2115, 2117, 2118, 2126, 2134, 2139, 2140,\n", - " 2142, 2145, 2147, 2148, 2155, 2156, 2160, 2161, 2168, 2169, 2175,\n", - " 2177, 2178, 2186, 2188, 2190, 2191, 2199, 2201, 2221, 2224, 2226,\n", - " 2229, 2230, 2232, 2239, 2243, 2246, 2247, 2248, 2249, 2250, 2254,\n", - " 2259, 2266, 2269, 2270, 2274, 2275, 2282, 2292, 2300, 2301, 2302,\n", - " 2304, 2305, 2306, 2311, 2312, 2320, 2323, 2327, 2332, 2342, 2346,\n", - " 2354, 2357, 2358, 2360, 2362, 2363, 2366, 2367, 2368, 2373, 2374,\n", - " 2375, 2376, 2377, 2379, 2382, 2385, 2388, 2392, 2397, 2399, 2407,\n", - " 2409, 2417, 2418, 2419, 2420, 2421, 2424, 2430, 2432, 2439, 2441,\n", - " 2443, 2449, 2451, 2454, 2465, 2474, 2478, 2498, 2499, 2501, 2502,\n", - " 2503, 2506, 2521, 2528, 2529, 2533, 2537, 2543, 2551, 2553, 2554,\n", - " 2556, 2564, 2569, 2572, 2573, 2576, 2578, 2580, 2585, 2587, 2600,\n", - " 2602, 2607, 2608, 2609, 2619, 2620, 2624, 2625, 2626, 2628, 2639,\n", - " 2640, 2648, 2651, 2658, 2664, 2673, 2679, 2680, 2697, 2698, 2708,\n", - " 2710, 2713, 2718, 2723, 2730, 2731, 2732, 2733, 2736, 2738, 2740,\n", - " 2741, 2743, 2746, 2749, 2751, 2752, 2756, 2761, 2766, 2767, 2782,\n", - " 2786, 2788, 2795, 2798, 2799, 2804, 2807, 2809, 2813, 2816, 2817,\n", - " 2821, 2822, 2826, 2836, 2841, 2850, 2854, 2859, 2865, 2867, 2869,\n", - " 2871, 2873, 2879, 2889, 2892, 2895, 2896, 2903, 2907, 2908, 2914,\n", - " 2917, 2923, 2927, 2929, 2932, 2936, 2941, 2946, 2948, 2949, 2957,\n", - " 2959, 2962, 2965, 2970, 2975, 2976, 2978, 2979, 2989, 2995, 2998,\n", - " 3001, 3003, 3005, 3006, 3008, 3014, 3017, 3018, 3021, 3023, 3028,\n", - " 3029, 3031, 3032, 3033, 3034, 3037, 3042, 3046, 3048, 3051, 3057,\n", - " 3063, 3066, 3074, 3081, 3083, 3085, 3103, 3106, 3113, 3114, 3121,\n", - " 3122, 3125, 3129, 3132, 3134, 3137, 3139, 3146, 3147, 3153, 3158,\n", - " 3160, 3169, 3171, 3172, 3177, 3179, 3188, 3189, 3190, 3192, 3199,\n", - " 3201, 3209, 3220, 3226, 3233, 3238, 3239, 3241, 3242, 3245, 3246,\n", - " 3249, 3250, 3251, 3252, 3253, 3254, 3260, 3261, 3264, 3265, 3268,\n", - " 3275, 3282, 3288, 3290, 3292, 3298, 3303, 3312, 3315, 3319, 3326,\n", - " 3328, 3330, 3339, 3347, 3351, 3360, 3361, 3373, 3375, 3379, 3381,\n", - " 3382, 3386, 3392, 3396, 3398, 3412, 3413, 3418, 3423, 3425, 3426,\n", - " 3430, 3433, 3434, 3436, 3442, 3447, 3452, 3456, 3461, 3465, 3474,\n", - " 3477, 3480, 3481, 3482, 3483, 3489, 3496, 3501, 3502, 3504, 3506,\n", - " 3510, 3514, 3517, 3518, 3519, 3524, 3527, 3530, 3533, 3534, 3536,\n", - " 3537, 3538, 3540, 3541, 3545, 3549, 3552, 3553, 3559, 3563, 3565,\n", - " 3566, 3572, 3575, 3577, 3579, 3580, 3583, 3586, 3587, 3597, 3598,\n", - " 3599, 3600, 3602, 3605, 3609, 3621])),\n", - " (2,\n", - " array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.]),\n", - " 27.835804541797003,\n", - " array([ 10, 11, 19, 22, 25, 26, 42, 44, 46, 71, 72,\n", - " 77, 85, 89, 94, 109, 110, 113, 123, 124, 144, 146,\n", - " 149, 151, 171, 174, 179, 184, 187, 194, 196, 197, 213,\n", - " 218, 224, 234, 243, 246, 248, 252, 253, 266, 271, 278,\n", - " 303, 307, 317, 321, 325, 333, 339, 341, 342, 357, 359,\n", - " 369, 376, 382, 395, 397, 409, 414, 416, 417, 421, 423,\n", - " 426, 436, 438, 445, 456, 457, 458, 467, 469, 480, 487,\n", - " 507, 510, 524, 527, 529, 535, 536, 547, 550, 551, 560,\n", - " 562, 566, 568, 569, 570, 571, 572, 575, 576, 582, 591,\n", - " 596, 602, 603, 605, 610, 617, 626, 644, 652, 658, 665,\n", - " 668, 670, 677, 680, 686, 689, 693, 700, 717, 726, 730,\n", - " 732, 740, 749, 753, 763, 766, 767, 772, 774, 776, 780,\n", - " 781, 785, 789, 792, 795, 810, 844, 848, 854, 856, 865,\n", - " 871, 874, 877, 881, 895, 896, 902, 903, 904, 906, 912,\n", - " 914, 915, 928, 935, 948, 957, 959, 963, 981, 986, 994,\n", - " 1014, 1020, 1025, 1045, 1055, 1065, 1099, 1123, 1134, 1136, 1141,\n", - " 1142, 1154, 1158, 1159, 1168, 1172, 1173, 1174, 1177, 1184, 1185,\n", - " 1191, 1193, 1199, 1200, 1201, 1206, 1222, 1223, 1229, 1230, 1234,\n", - " 1242, 1246, 1255, 1260, 1272, 1273, 1278, 1288, 1290, 1291, 1296,\n", - " 1316, 1325, 1326, 1334, 1336, 1343, 1345, 1348, 1350, 1353, 1359,\n", - " 1368, 1369, 1374, 1375, 1381, 1385, 1391, 1393, 1410, 1411, 1432,\n", - " 1451, 1462, 1483, 1516, 1517, 1519, 1525, 1527, 1529, 1530, 1541,\n", - " 1546, 1548, 1556, 1559, 1565, 1573, 1583, 1597, 1600, 1609, 1617,\n", - " 1621, 1624, 1625, 1629, 1633, 1634, 1642, 1646, 1647, 1649, 1651,\n", - " 1659, 1667, 1672, 1677, 1689, 1699, 1716, 1717, 1718, 1720, 1742,\n", - " 1748, 1757, 1764, 1767, 1772, 1777, 1786, 1792, 1804, 1809, 1812,\n", - " 1813, 1825, 1826, 1828, 1842, 1854, 1873, 1882, 1884, 1900, 1902,\n", - " 1906, 1911, 1935, 1942, 1948, 1951, 1954, 1964, 1968, 1988, 1993,\n", - " 1994, 1995, 1997, 2010, 2024, 2026, 2029, 2037, 2046, 2059, 2060,\n", - " 2072, 2075, 2078, 2082, 2098, 2099, 2107, 2109, 2111, 2119, 2121,\n", - " 2128, 2136, 2152, 2157, 2170, 2171, 2172, 2176, 2192, 2194, 2205,\n", - " 2215, 2217, 2218, 2222, 2223, 2225, 2236, 2242, 2261, 2276, 2277,\n", - " 2279, 2281, 2303, 2307, 2308, 2315, 2322, 2328, 2348, 2353, 2361,\n", - " 2365, 2378, 2383, 2386, 2389, 2390, 2391, 2398, 2406, 2408, 2410,\n", - " 2434, 2436, 2437, 2442, 2444, 2457, 2458, 2460, 2461, 2463, 2467,\n", - " 2480, 2486, 2493, 2497, 2505, 2508, 2510, 2522, 2524, 2526, 2534,\n", - " 2544, 2548, 2549, 2552, 2557, 2561, 2582, 2586, 2590, 2592, 2595,\n", - " 2601, 2606, 2632, 2650, 2652, 2655, 2663, 2665, 2666, 2668, 2669,\n", - " 2672, 2674, 2681, 2687, 2690, 2691, 2693, 2699, 2711, 2720, 2722,\n", - " 2727, 2734, 2745, 2747, 2758, 2759, 2769, 2771, 2772, 2775, 2781,\n", - " 2783, 2787, 2789, 2796, 2810, 2811, 2820, 2827, 2833, 2839, 2840,\n", - " 2842, 2843, 2847, 2853, 2860, 2875, 2876, 2881, 2888, 2894, 2901,\n", - " 2904, 2916, 2919, 2928, 2950, 2954, 2960, 2963, 2966, 2986, 2987,\n", - " 2992, 2994, 2999, 3000, 3007, 3039, 3059, 3061, 3064, 3067, 3073,\n", - " 3078, 3082, 3087, 3088, 3090, 3099, 3104, 3112, 3126, 3127, 3131,\n", - " 3135, 3144, 3149, 3150, 3154, 3155, 3157, 3162, 3170, 3175, 3180,\n", - " 3181, 3182, 3183, 3184, 3187, 3197, 3204, 3210, 3216, 3221, 3225,\n", - " 3227, 3230, 3235, 3236, 3243, 3244, 3271, 3272, 3276, 3278, 3283,\n", - " 3289, 3293, 3304, 3305, 3306, 3307, 3318, 3324, 3329, 3346, 3348,\n", - " 3350, 3352, 3358, 3362, 3383, 3385, 3388, 3405, 3408, 3422, 3437,\n", - " 3439, 3446, 3448, 3450, 3486, 3507, 3512, 3513, 3516, 3522, 3523,\n", - " 3554, 3560, 3569, 3573, 3574, 3584, 3593, 3595, 3601, 3606, 3613,\n", - " 3614])),\n", - " (3,\n", - " array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1.]),\n", - " 19.20965012246301,\n", - " array([ 4, 5, 13, 30, 54, 59, 61, 76, 78, 82, 98,\n", - " 104, 112, 129, 132, 142, 143, 152, 155, 156, 167, 168,\n", - " 180, 181, 185, 203, 209, 222, 225, 239, 245, 251, 258,\n", - " 262, 269, 272, 284, 290, 305, 312, 316, 337, 347, 349,\n", - " 350, 352, 354, 362, 377, 385, 394, 413, 422, 425, 428,\n", - " 429, 439, 440, 441, 447, 448, 453, 459, 463, 464, 488,\n", - " 492, 496, 500, 509, 520, 521, 523, 525, 526, 533, 549,\n", - " 557, 558, 567, 574, 587, 593, 606, 607, 625, 627, 634,\n", - " 655, 663, 667, 674, 679, 683, 696, 718, 719, 729, 748,\n", - " 760, 769, 796, 800, 801, 807, 816, 818, 832, 835, 850,\n", - " 858, 862, 870, 875, 880, 884, 886, 889, 892, 897, 920,\n", - " 940, 944, 954, 958, 979, 985, 988, 991, 1002, 1010, 1027,\n", - " 1028, 1033, 1039, 1041, 1050, 1052, 1053, 1084, 1085, 1098, 1103,\n", - " 1109, 1116, 1122, 1146, 1156, 1163, 1166, 1170, 1190, 1195, 1203,\n", - " 1209, 1215, 1216, 1221, 1237, 1248, 1251, 1265, 1266, 1268, 1274,\n", - " 1298, 1304, 1318, 1322, 1347, 1349, 1377, 1390, 1392, 1404, 1417,\n", - " 1420, 1430, 1433, 1438, 1441, 1443, 1448, 1449, 1457, 1458, 1459,\n", - " 1465, 1476, 1485, 1488, 1502, 1510, 1515, 1523, 1533, 1536, 1538,\n", - " 1558, 1571, 1574, 1579, 1586, 1592, 1593, 1602, 1607, 1623, 1632,\n", - " 1636, 1637, 1638, 1639, 1652, 1670, 1673, 1682, 1683, 1684, 1698,\n", - " 1719, 1735, 1744, 1745, 1752, 1756, 1763, 1768, 1776, 1790, 1795,\n", - " 1796, 1807, 1823, 1830, 1837, 1839, 1840, 1841, 1852, 1877, 1879,\n", - " 1889, 1930, 1939, 1944, 1945, 1959, 1969, 1978, 1985, 1987, 1996,\n", - " 2007, 2014, 2018, 2030, 2043, 2044, 2066, 2081, 2095, 2101, 2105,\n", - " 2108, 2125, 2129, 2137, 2143, 2150, 2153, 2185, 2196, 2206, 2212,\n", - " 2214, 2216, 2231, 2235, 2262, 2272, 2278, 2298, 2310, 2318, 2324,\n", - " 2333, 2343, 2359, 2372, 2381, 2394, 2395, 2400, 2425, 2429, 2446,\n", - " 2462, 2470, 2471, 2472, 2475, 2477, 2484, 2485, 2487, 2488, 2489,\n", - " 2511, 2523, 2538, 2541, 2563, 2568, 2617, 2629, 2644, 2649, 2670,\n", - " 2676, 2683, 2685, 2695, 2696, 2819, 2823, 2825, 2830, 2834, 2838,\n", - " 2846, 2863, 2870, 2883, 2893, 2910, 2912, 2921, 2930, 2931, 2933,\n", - " 2939, 2940, 2942, 2945, 2958, 2971, 2980, 3013, 3015, 3016, 3019,\n", - " 3026, 3027, 3049, 3050, 3060, 3076, 3086, 3092, 3093, 3094, 3096,\n", - " 3100, 3110, 3115, 3120, 3130, 3133, 3136, 3141, 3143, 3159, 3165,\n", - " 3186, 3191, 3195, 3198, 3202, 3211, 3215, 3222, 3223, 3228, 3229,\n", - " 3234, 3248, 3257, 3258, 3280, 3281, 3286, 3291, 3314, 3317, 3325,\n", - " 3327, 3340, 3355, 3368, 3370, 3387, 3395, 3402, 3407, 3414, 3417,\n", - " 3420, 3428, 3435, 3451, 3454, 3455, 3464, 3479, 3487, 3491, 3493,\n", - " 3495, 3535, 3558, 3564, 3590, 3592, 3607, 3610, 3612, 3615, 3619,\n", - " 3620, 3624])),\n", - " (4,\n", - " array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.]),\n", - " 23.6344423140483,\n", - " array([ 17, 23, 24, 36, 37, 39, 40, 50, 62, 66, 67,\n", - " 75, 81, 91, 92, 100, 119, 125, 158, 162, 166, 176,\n", - " 186, 191, 195, 200, 208, 210, 220, 233, 237, 244, 250,\n", - " 257, 259, 263, 273, 293, 294, 314, 319, 322, 330, 344,\n", - " 348, 353, 360, 387, 401, 402, 461, 468, 475, 478, 482,\n", - " 493, 494, 495, 498, 501, 506, 511, 515, 518, 528, 541,\n", - " 556, 561, 577, 578, 601, 611, 612, 615, 618, 620, 623,\n", - " 640, 645, 656, 664, 666, 681, 688, 691, 694, 699, 710,\n", - " 711, 722, 723, 724, 733, 734, 745, 755, 764, 770, 771,\n", - " 777, 790, 794, 799, 803, 812, 830, 836, 841, 843, 849,\n", - " 852, 860, 879, 882, 885, 900, 909, 919, 926, 933, 936,\n", - " 943, 951, 956, 961, 964, 980, 983, 992, 1007, 1012, 1013,\n", - " 1029, 1034, 1047, 1048, 1051, 1054, 1056, 1058, 1061, 1064, 1080,\n", - " 1081, 1086, 1087, 1088, 1091, 1092, 1095, 1111, 1113, 1119, 1121,\n", - " 1125, 1126, 1127, 1145, 1149, 1150, 1164, 1167, 1176, 1181, 1205,\n", - " 1207, 1208, 1219, 1228, 1235, 1236, 1239, 1240, 1250, 1264, 1276,\n", - " 1299, 1300, 1303, 1306, 1311, 1314, 1328, 1332, 1342, 1351, 1363,\n", - " 1370, 1371, 1376, 1380, 1386, 1387, 1398, 1399, 1403, 1422, 1423,\n", - " 1435, 1437, 1439, 1442, 1447, 1467, 1470, 1472, 1479, 1489, 1492,\n", - " 1499, 1504, 1508, 1514, 1526, 1537, 1547, 1551, 1555, 1561, 1562,\n", - " 1564, 1575, 1596, 1608, 1611, 1612, 1635, 1641, 1675, 1676, 1678,\n", - " 1681, 1693, 1694, 1695, 1696, 1697, 1700, 1703, 1714, 1721, 1722,\n", - " 1723, 1732, 1747, 1753, 1758, 1759, 1761, 1765, 1774, 1805, 1819,\n", - " 1844, 1845, 1846, 1847, 1849, 1871, 1881, 1885, 1892, 1898, 1908,\n", - " 1910, 1927, 1928, 1949, 1950, 1961, 1967, 1977, 1982, 1983, 1986,\n", - " 1989, 1990, 2011, 2019, 2020, 2023, 2040, 2042, 2045, 2050, 2054,\n", - " 2057, 2058, 2085, 2087, 2097, 2100, 2106, 2110, 2123, 2130, 2141,\n", - " 2151, 2158, 2163, 2179, 2187, 2193, 2195, 2197, 2202, 2207, 2208,\n", - " 2227, 2237, 2238, 2244, 2256, 2258, 2263, 2287, 2299, 2319, 2325,\n", - " 2326, 2329, 2330, 2336, 2340, 2345, 2384, 2387, 2401, 2414, 2416,\n", - " 2426, 2427, 2431, 2433, 2452, 2456, 2459, 2468, 2483, 2492, 2494,\n", - " 2496, 2500, 2504, 2512, 2515, 2516, 2520, 2525, 2540, 2560, 2566,\n", - " 2567, 2570, 2571, 2581, 2599, 2605, 2613, 2616, 2630, 2634, 2635,\n", - " 2637, 2641, 2645, 2653, 2656, 2657, 2675, 2678, 2709, 2725, 2737,\n", - " 2753, 2760, 2762, 2763, 2784, 2797, 2800, 2801, 2808, 2815, 2832,\n", - " 2837, 2844, 2845, 2851, 2868, 2880, 2886, 2887, 2897, 2899, 2905,\n", - " 2915, 2925, 2937, 2938, 2944, 2947, 2951, 2952, 2956, 2961, 2968,\n", - " 2977, 2991, 3004, 3038, 3058, 3065, 3068, 3070, 3071, 3075, 3097,\n", - " 3102, 3105, 3109, 3117, 3119, 3123, 3140, 3152, 3161, 3163, 3164,\n", - " 3167, 3176, 3194, 3196, 3200, 3207, 3212, 3219, 3224, 3255, 3274,\n", - " 3277, 3279, 3284, 3285, 3295, 3297, 3299, 3300, 3308, 3310, 3321,\n", - " 3322, 3323, 3333, 3334, 3337, 3338, 3343, 3344, 3354, 3364, 3372,\n", - " 3378, 3384, 3394, 3409, 3411, 3416, 3427, 3438, 3440, 3441, 3449,\n", - " 3463, 3469, 3475, 3476, 3484, 3485, 3508, 3509, 3511, 3528, 3531,\n", - " 3539, 3542, 3555, 3561, 3603, 3608, 3622])),\n", - " (5,\n", - " array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.]),\n", - " 16.251921424887335,\n", - " array([ 12, 14, 15, 35, 45, 49, 51, 63, 65, 68, 79,\n", - " 105, 139, 141, 147, 150, 153, 154, 178, 217, 219, 231,\n", - " 236, 238, 254, 264, 274, 277, 288, 301, 306, 326, 328,\n", - " 329, 346, 355, 358, 364, 365, 371, 375, 378, 379, 384,\n", - " 389, 390, 391, 396, 411, 427, 431, 444, 477, 481, 491,\n", - " 517, 543, 544, 555, 588, 594, 608, 616, 628, 639, 643,\n", - " 662, 671, 682, 703, 752, 775, 782, 784, 788, 793, 798,\n", - " 811, 827, 828, 845, 864, 869, 898, 913, 921, 938, 949,\n", - " 953, 962, 966, 972, 977, 987, 996, 1003, 1004, 1008, 1019,\n", - " 1023, 1038, 1042, 1049, 1068, 1069, 1074, 1076, 1078, 1089, 1102,\n", - " 1105, 1128, 1153, 1155, 1162, 1179, 1182, 1198, 1211, 1212, 1217,\n", - " 1218, 1225, 1231, 1232, 1241, 1245, 1257, 1262, 1269, 1270, 1281,\n", - " 1286, 1294, 1297, 1309, 1312, 1323, 1327, 1339, 1341, 1360, 1378,\n", - " 1383, 1388, 1389, 1400, 1401, 1413, 1416, 1450, 1455, 1463, 1477,\n", - " 1484, 1494, 1495, 1505, 1506, 1522, 1534, 1544, 1549, 1550, 1554,\n", - " 1569, 1572, 1588, 1598, 1613, 1622, 1626, 1630, 1644, 1666, 1669,\n", - " 1686, 1708, 1724, 1727, 1737, 1743, 1749, 1771, 1793, 1799, 1801,\n", - " 1803, 1808, 1814, 1817, 1835, 1853, 1868, 1872, 1895, 1896, 1912,\n", - " 1914, 1916, 1922, 1931, 1933, 1946, 1974, 1992, 2005, 2033, 2052,\n", - " 2053, 2062, 2069, 2073, 2074, 2089, 2091, 2094, 2103, 2113, 2116,\n", - " 2122, 2127, 2135, 2149, 2154, 2162, 2164, 2166, 2180, 2181, 2182,\n", - " 2209, 2211, 2245, 2253, 2257, 2268, 2271, 2288, 2290, 2296, 2316,\n", - " 2334, 2337, 2338, 2339, 2341, 2347, 2349, 2351, 2355, 2356, 2405,\n", - " 2413, 2422, 2428, 2438, 2440, 2448, 2455, 2464, 2473, 2479, 2482,\n", - " 2490, 2509, 2517, 2531, 2550, 2555, 2558, 2574, 2575, 2583, 2589,\n", - " 2591, 2597, 2611, 2614, 2618, 2627, 2633, 2636, 2643, 2682, 2700,\n", - " 2704, 2707, 2716, 2721, 2726, 2754, 2764, 2765, 2793, 2794, 2805,\n", - " 2814, 2835, 2852, 2855, 2856, 2862, 2866, 2878, 2891, 2909, 2918,\n", - " 2920, 2924, 2974, 2982, 2993, 3011, 3020, 3022, 3040, 3041, 3044,\n", - " 3054, 3056, 3091, 3101, 3107, 3108, 3111, 3142, 3151, 3156, 3203,\n", - " 3206, 3213, 3217, 3231, 3269, 3309, 3313, 3331, 3332, 3335, 3342,\n", - " 3349, 3359, 3374, 3389, 3400, 3403, 3445, 3453, 3460, 3467, 3492,\n", - " 3498, 3500, 3515, 3521, 3525, 3526, 3529, 3543, 3568, 3571, 3585,\n", - " 3588, 3589, 3591, 3594, 3604]))]" - ] - }, - "execution_count": 121, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ - "# here the information for all the combinations\n", - "freq_wrap.iter_columns()" + "(cat_id_0_column * weights[cat_id_0_nz]).sum()" ] }, { "cell_type": "code", - "execution_count": 133, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(0,\n", - " array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.]),\n", - " 46.529753144154704,\n", - " array([ 0, 1, 2, 7, 16, 18, 20, 27, 32, 34, 38,\n", - " 41, 47, 58, 60, 74, 84, 86, 87, 88, 90, 95,\n", - " 97, 99, 106, 107, 108, 115, 116, 118, 121, 122, 130,\n", - " 131, 135, 138, 140, 159, 163, 165, 169, 175, 182, 190,\n", - " 192, 205, 207, 211, 212, 214, 215, 221, 223, 226, 227,\n", - " 228, 229, 232, 235, 240, 242, 256, 261, 268, 270, 279,\n", - " 280, 281, 282, 283, 285, 287, 291, 295, 297, 298, 299,\n", - " 300, 308, 309, 310, 311, 315, 320, 324, 331, 332, 336,\n", - " 338, 345, 356, 361, 363, 366, 367, 368, 372, 380, 383,\n", - " 388, 393, 400, 403, 406, 408, 418, 419, 430, 432, 433,\n", - " 434, 449, 450, 465, 466, 471, 472, 473, 483, 486, 499,\n", - " 504, 513, 514, 519, 537, 538, 540, 545, 546, 548, 552,\n", - " 553, 559, 565, 573, 579, 580, 583, 585, 589, 590, 597,\n", - " 598, 609, 613, 622, 624, 629, 632, 635, 636, 637, 638,\n", - " 641, 642, 646, 649, 650, 660, 661, 669, 672, 673, 684,\n", - " 687, 692, 697, 698, 706, 713, 716, 725, 727, 737, 738,\n", - " 739, 741, 747, 751, 754, 761, 762, 768, 797, 804, 805,\n", - " 809, 814, 815, 820, 822, 824, 825, 826, 837, 839, 840,\n", - " 842, 847, 855, 863, 866, 868, 872, 876, 887, 891, 901,\n", - " 905, 911, 916, 917, 923, 937, 939, 942, 945, 946, 952,\n", - " 960, 967, 969, 970, 973, 974, 975, 978, 984, 989, 990,\n", - " 993, 997, 999, 1000, 1005, 1006, 1009, 1011, 1015, 1021, 1022,\n", - " 1024, 1031, 1037, 1040, 1043, 1044, 1057, 1059, 1062, 1063, 1071,\n", - " 1072, 1073, 1079, 1083, 1090, 1093, 1094, 1096, 1097, 1101, 1106,\n", - " 1107, 1108, 1114, 1118, 1124, 1130, 1137, 1138, 1140, 1143, 1144,\n", - " 1161, 1171, 1175, 1178, 1180, 1186, 1187, 1188, 1192, 1196, 1197,\n", - " 1204, 1226, 1247, 1252, 1253, 1254, 1256, 1259, 1261, 1263, 1267,\n", - " 1271, 1279, 1285, 1292, 1295, 1302, 1305, 1308, 1317, 1319, 1321,\n", - " 1324, 1331, 1333, 1335, 1354, 1355, 1357, 1358, 1361, 1362, 1366,\n", - " 1367, 1373, 1382, 1395, 1396, 1397, 1406, 1407, 1408, 1409, 1415,\n", - " 1421, 1425, 1426, 1427, 1429, 1434, 1444, 1445, 1452, 1456, 1460,\n", - " 1461, 1466, 1474, 1480, 1481, 1482, 1490, 1491, 1493, 1501, 1509,\n", - " 1521, 1528, 1545, 1552, 1566, 1567, 1570, 1576, 1577, 1580, 1582,\n", - " 1594, 1603, 1605, 1618, 1619, 1627, 1628, 1643, 1645, 1650, 1653,\n", - " 1654, 1655, 1657, 1660, 1661, 1662, 1664, 1674, 1679, 1688, 1691,\n", - " 1692, 1701, 1704, 1705, 1709, 1710, 1711, 1712, 1713, 1715, 1729,\n", - " 1730, 1731, 1738, 1739, 1741, 1746, 1751, 1766, 1770, 1779, 1783,\n", - " 1785, 1787, 1800, 1802, 1811, 1816, 1820, 1821, 1824, 1829, 1833,\n", - " 1843, 1848, 1850, 1851, 1856, 1861, 1865, 1866, 1867, 1870, 1874,\n", - " 1875, 1878, 1883, 1887, 1890, 1891, 1893, 1897, 1903, 1904, 1905,\n", - " 1907, 1917, 1918, 1920, 1923, 1924, 1932, 1934, 1937, 1947, 1953,\n", - " 1957, 1958, 1962, 1965, 1971, 1972, 1975, 1976, 1979, 1980, 1998,\n", - " 2000, 2003, 2008, 2013, 2021, 2025, 2028, 2032, 2034, 2036, 2041,\n", - " 2048, 2049, 2056, 2061, 2064, 2068, 2070, 2076, 2080, 2086, 2090,\n", - " 2093, 2096, 2102, 2112, 2120, 2124, 2131, 2132, 2133, 2138, 2144,\n", - " 2146, 2159, 2165, 2167, 2173, 2174, 2183, 2184, 2189, 2198, 2200,\n", - " 2203, 2204, 2210, 2213, 2219, 2220, 2228, 2233, 2234, 2240, 2241,\n", - " 2251, 2252, 2255, 2260, 2264, 2265, 2267, 2273, 2280, 2283, 2284,\n", - " 2285, 2286, 2289, 2291, 2293, 2294, 2295, 2297, 2309, 2313, 2314,\n", - " 2317, 2321, 2331, 2335, 2344, 2350, 2352, 2364, 2369, 2370, 2371,\n", - " 2380, 2393, 2396, 2402, 2403, 2404, 2411, 2412, 2415, 2423, 2435,\n", - " 2445, 2447, 2450, 2453, 2466, 2469, 2476, 2481, 2491, 2495, 2507,\n", - " 2513, 2514, 2518, 2519, 2527, 2530, 2532, 2535, 2536, 2539, 2542,\n", - " 2545, 2546, 2547, 2559, 2562, 2565, 2577, 2579, 2584, 2588, 2593,\n", - " 2594, 2596, 2598, 2603, 2604, 2610, 2612, 2615, 2621, 2622, 2623,\n", - " 2631, 2638, 2642, 2646, 2647, 2654, 2659, 2660, 2661, 2662, 2667,\n", - " 2671, 2677, 2684, 2686, 2688, 2689, 2692, 2694, 2701, 2702, 2703,\n", - " 2705, 2706, 2712, 2714, 2715, 2717, 2719, 2724, 2728, 2729, 2735,\n", - " 2739, 2742, 2744, 2748, 2750, 2755, 2757, 2768, 2770, 2773, 2774,\n", - " 2776, 2777, 2778, 2779, 2780, 2785, 2790, 2791, 2792, 2802, 2803,\n", - " 2806, 2812, 2818, 2824, 2828, 2829, 2831, 2848, 2849, 2857, 2858,\n", - " 2861, 2864, 2872, 2874, 2877, 2882, 2884, 2885, 2890, 2898, 2900,\n", - " 2902, 2906, 2911, 2913, 2922, 2926, 2934, 2935, 2943, 2953, 2955,\n", - " 2964, 2967, 2969, 2972, 2973, 2981, 2983, 2984, 2985, 2988, 2990,\n", - " 2996, 2997, 3002, 3009, 3010, 3012, 3024, 3025, 3030, 3035, 3036,\n", - " 3043, 3045, 3047, 3052, 3053, 3055, 3062, 3069, 3072, 3077, 3079,\n", - " 3080, 3084, 3089, 3095, 3098, 3116, 3118, 3124, 3128, 3138, 3145,\n", - " 3148, 3166, 3168, 3173, 3174, 3178, 3185, 3193, 3205, 3208, 3214,\n", - " 3218, 3232, 3237, 3240, 3247, 3256, 3259, 3262, 3263, 3266, 3267,\n", - " 3270, 3273, 3287, 3294, 3296, 3301, 3302, 3311, 3316, 3320, 3336,\n", - " 3341, 3345, 3353, 3356, 3357, 3363, 3365, 3366, 3367, 3369, 3371,\n", - " 3376, 3377, 3380, 3390, 3391, 3393, 3397, 3399, 3401, 3404, 3406,\n", - " 3410, 3415, 3419, 3421, 3424, 3429, 3431, 3432, 3443, 3444, 3457,\n", - " 3458, 3459, 3462, 3466, 3468, 3470, 3471, 3472, 3473, 3478, 3488,\n", - " 3490, 3494, 3497, 3499, 3503, 3505, 3520, 3532, 3544, 3546, 3547,\n", - " 3548, 3550, 3551, 3556, 3557, 3562, 3567, 3570, 3576, 3578, 3581,\n", - " 3582, 3596, 3611, 3616, 3617, 3618, 3623]))" - ] - }, - "execution_count": 133, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ - "# and here, we can see for category \"0\" that non zero values are...\n", - "freq_wrap.get_column(0)" + "# Here the total households with no car and no children(843)\n", + "jd_households" ] }, { - "cell_type": "code", - "execution_count": 135, + "cell_type": "markdown", "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "hh_id\n", - "0 1.0\n", - "2 1.0\n", - "3 1.0\n", - "4 0.0\n", - "5 0.0\n", - "13 0.0\n", - "14 0.0\n", - "15 1.0\n", - "Name: 0, dtype: float64" - ] - }, - "execution_count": 135, - "metadata": {}, - "output_type": "execute_result" - } - ], "source": [ - "#... in the index 0, 1, 2, 7, (...)\n", - "h_freq_table[0][0:8]" + "The sum of non zero values is weighted and then reduced by substracting the constraints..." ] }, { @@ -5176,320 +1727,223 @@ "execution_count": null, "metadata": {}, "outputs": [], - "source": [] + "source": [ + "(cat_id_0_column * weights[cat_id_0_nz]).sum() - constraint" + ] }, { - "cell_type": "code", - "execution_count": null, + "cell_type": "markdown", "metadata": {}, - "outputs": [], - "source": [] + "source": [ + "... and finally is expressed in terms of the constraint for that category - the 𝛿 parameter described in the IPU paper -. The absolute value of the relative difference between the weighted sum and the corresponding constraint may be used as a goodness of fit measure and is defined as: " + ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], - "source": [] + "source": [ + "((cat_id_0_column * weights[cat_id_0_nz]).sum() - constraint) / constraint" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This is basically showing the proportion of the `cat_id` within the entire population of the PUMA. In the example of this first iteration, we have that for each household that `cat_id` == `0`, there are 17 households that could be out of that category (`cat_id` != `0`). " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "![constraints](img/ipu.png)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This process will be repeated for all household types (or `cat_id`) and build a unique average value (which is the sum of each `_fit_quality` result divided by the number of `cat_id` columns):" + ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], - "source": [] + "source": [ + "fit_qual_0_to_5 = _average_fit_quality(freq_wrap, weights)" + ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], - "source": [] + "source": [ + "fit_qual_0_to_5" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "As it is explained on [A METHODOLOGY TO MATCH DISTRIBUTIONS OF BOTH HOUSEHOLD AND\n", + "PERSON ATTRIBUTES IN THE GENERATION OF SYNTHETIC POPULATIONS ](http://www.scag.ca.gov/Documents/PopulationSynthesizerPaper_TRB.pdf), the IPU algorithm starts by assuming equal weights for all households in the sample. The algorithm then proceeds by adjusting weights for each household/person constraint in an iterative process until the constraints are matched as closely as possible for both household and person attributes. " + ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], - "source": [] + "source": [ + "fit_change = np.inf\n", + "convergence= 1e-4" + ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], - "source": [] + "source": [ + "if fit_change > convergence:\n", + " print(\"Updating weights matrix until reaching a fit quality value under the convergence!\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The weights for the each household level constraint are adjusted by dividing the number of households in that category (i.e., the constraint value) by the weighted sum of the first household type column: \n", + "\n", + "The `_update_weights` creates the following adjustment `adj = constraint / float((column * weights).sum())` and use it to update weights (`weights * adj`). The weights for all households of each household type will be multiplied by this ratio to satisfy the constraint. " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In this sense, the `households_weights` function will finally return a:" + ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], - "source": [] + "source": [ + "# 1. An array of corrected weights that best matches each household type \n", + "best_weights" + ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], - "source": [] + "source": [ + "# 2. And a fit quality based on the proportion of each hh type that reduces the fit changes under the convergence \n", + "fit_quality" + ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], - "source": [] + "source": [ + "# 3. Built in ...\n", + "iterations" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 4. Drawing synthetic population " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "![draw](img/draw.png)" + ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], - "source": [] + "source": [ + "from synthpop import draw" + ] }, { "cell_type": "code", - "execution_count": 93, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ - "def _drop_zeros(df):\n", - " \"\"\"\n", - " Drop zeros from a DataFrame, returning an iterator over the columns\n", - " in the DataFrame.\n", - "\n", - " Yields tuples of (column name, non-zero column values, non-zero indexes).\n", - "\n", - " Parameters\n", - " ----------\n", - " df : pandas.DataFrame\n", - "\n", - " \"\"\"\n", - " def for_each_col(col):\n", - " nz = col.nonzero()[0]\n", - " return col[nz], nz\n", - "\n", - " for (col_idx, (col, nz)) in df.apply(for_each_col, axis=0, raw=True).items():\n", - " return (col_idx, col, nz)" + "num_households = int(hh_marginals_tract_400_block_gp_1.groupby(level=0).sum().mean())" ] }, { "cell_type": "code", - "execution_count": 94, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ - "df = h_freq_table.copy()" + "num_households" ] }, { "cell_type": "code", - "execution_count": 95, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ - "def for_each_col(col):\n", - " nz = col.nonzero()[0]\n", - " return col[nz], nz" + "fac = _FrequencyAndConstraints(h_freq_table, h_constraint)" ] }, { "cell_type": "code", - "execution_count": 102, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ - "for (col_idx, (col, nz)) in df.apply(for_each_col, axis=0, raw=True).items():\n", - " d = (col_idx, col, nz)" + "indexes = draw._draw_indexes(num_households, fac, best_weights)" ] }, { "cell_type": "code", - "execution_count": 136, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(5,\n", - " array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.]),\n", - " array([ 12, 14, 15, 35, 45, 49, 51, 63, 65, 68, 79,\n", - " 105, 139, 141, 147, 150, 153, 154, 178, 217, 219, 231,\n", - " 236, 238, 254, 264, 274, 277, 288, 301, 306, 326, 328,\n", - " 329, 346, 355, 358, 364, 365, 371, 375, 378, 379, 384,\n", - " 389, 390, 391, 396, 411, 427, 431, 444, 477, 481, 491,\n", - " 517, 543, 544, 555, 588, 594, 608, 616, 628, 639, 643,\n", - " 662, 671, 682, 703, 752, 775, 782, 784, 788, 793, 798,\n", - " 811, 827, 828, 845, 864, 869, 898, 913, 921, 938, 949,\n", - " 953, 962, 966, 972, 977, 987, 996, 1003, 1004, 1008, 1019,\n", - " 1023, 1038, 1042, 1049, 1068, 1069, 1074, 1076, 1078, 1089, 1102,\n", - " 1105, 1128, 1153, 1155, 1162, 1179, 1182, 1198, 1211, 1212, 1217,\n", - " 1218, 1225, 1231, 1232, 1241, 1245, 1257, 1262, 1269, 1270, 1281,\n", - " 1286, 1294, 1297, 1309, 1312, 1323, 1327, 1339, 1341, 1360, 1378,\n", - " 1383, 1388, 1389, 1400, 1401, 1413, 1416, 1450, 1455, 1463, 1477,\n", - " 1484, 1494, 1495, 1505, 1506, 1522, 1534, 1544, 1549, 1550, 1554,\n", - " 1569, 1572, 1588, 1598, 1613, 1622, 1626, 1630, 1644, 1666, 1669,\n", - " 1686, 1708, 1724, 1727, 1737, 1743, 1749, 1771, 1793, 1799, 1801,\n", - " 1803, 1808, 1814, 1817, 1835, 1853, 1868, 1872, 1895, 1896, 1912,\n", - " 1914, 1916, 1922, 1931, 1933, 1946, 1974, 1992, 2005, 2033, 2052,\n", - " 2053, 2062, 2069, 2073, 2074, 2089, 2091, 2094, 2103, 2113, 2116,\n", - " 2122, 2127, 2135, 2149, 2154, 2162, 2164, 2166, 2180, 2181, 2182,\n", - " 2209, 2211, 2245, 2253, 2257, 2268, 2271, 2288, 2290, 2296, 2316,\n", - " 2334, 2337, 2338, 2339, 2341, 2347, 2349, 2351, 2355, 2356, 2405,\n", - " 2413, 2422, 2428, 2438, 2440, 2448, 2455, 2464, 2473, 2479, 2482,\n", - " 2490, 2509, 2517, 2531, 2550, 2555, 2558, 2574, 2575, 2583, 2589,\n", - " 2591, 2597, 2611, 2614, 2618, 2627, 2633, 2636, 2643, 2682, 2700,\n", - " 2704, 2707, 2716, 2721, 2726, 2754, 2764, 2765, 2793, 2794, 2805,\n", - " 2814, 2835, 2852, 2855, 2856, 2862, 2866, 2878, 2891, 2909, 2918,\n", - " 2920, 2924, 2974, 2982, 2993, 3011, 3020, 3022, 3040, 3041, 3044,\n", - " 3054, 3056, 3091, 3101, 3107, 3108, 3111, 3142, 3151, 3156, 3203,\n", - " 3206, 3213, 3217, 3231, 3269, 3309, 3313, 3331, 3332, 3335, 3342,\n", - " 3349, 3359, 3374, 3389, 3400, 3403, 3445, 3453, 3460, 3467, 3492,\n", - " 3498, 3500, 3515, 3521, 3525, 3526, 3529, 3543, 3568, 3571, 3585,\n", - " 3588, 3589, 3591, 3594, 3604]))" - ] - }, - "execution_count": 136, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ - "d" + "indexes" ] }, { "cell_type": "code", - "execution_count": 141, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "hh_id\n", - "0 0.0\n", - "2 0.0\n", - "3 0.0\n", - "4 0.0\n", - "5 0.0\n", - "13 0.0\n", - "14 0.0\n", - "15 0.0\n", - "17 0.0\n", - "18 0.0\n", - "19 0.0\n", - "23 0.0\n", - "24 1.0\n", - "25 0.0\n", - "26 1.0\n", - "Name: 5, dtype: float64" - ] - }, - "execution_count": 141, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ - "h_freq_table[5][:15]" + "synth_hh = h_pums.loc[indexes].reset_index(drop=True)" ] }, { "cell_type": "code", - "execution_count": 104, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(5,\n", - " array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.]),\n", - " array([ 12, 14, 15, 35, 45, 49, 51, 63, 65, 68, 79,\n", - " 105, 139, 141, 147, 150, 153, 154, 178, 217, 219, 231,\n", - " 236, 238, 254, 264, 274, 277, 288, 301, 306, 326, 328,\n", - " 329, 346, 355, 358, 364, 365, 371, 375, 378, 379, 384,\n", - " 389, 390, 391, 396, 411, 427, 431, 444, 477, 481, 491,\n", - " 517, 543, 544, 555, 588, 594, 608, 616, 628, 639, 643,\n", - " 662, 671, 682, 703, 752, 775, 782, 784, 788, 793, 798,\n", - " 811, 827, 828, 845, 864, 869, 898, 913, 921, 938, 949,\n", - " 953, 962, 966, 972, 977, 987, 996, 1003, 1004, 1008, 1019,\n", - " 1023, 1038, 1042, 1049, 1068, 1069, 1074, 1076, 1078, 1089, 1102,\n", - " 1105, 1128, 1153, 1155, 1162, 1179, 1182, 1198, 1211, 1212, 1217,\n", - " 1218, 1225, 1231, 1232, 1241, 1245, 1257, 1262, 1269, 1270, 1281,\n", - " 1286, 1294, 1297, 1309, 1312, 1323, 1327, 1339, 1341, 1360, 1378,\n", - " 1383, 1388, 1389, 1400, 1401, 1413, 1416, 1450, 1455, 1463, 1477,\n", - " 1484, 1494, 1495, 1505, 1506, 1522, 1534, 1544, 1549, 1550, 1554,\n", - " 1569, 1572, 1588, 1598, 1613, 1622, 1626, 1630, 1644, 1666, 1669,\n", - " 1686, 1708, 1724, 1727, 1737, 1743, 1749, 1771, 1793, 1799, 1801,\n", - " 1803, 1808, 1814, 1817, 1835, 1853, 1868, 1872, 1895, 1896, 1912,\n", - " 1914, 1916, 1922, 1931, 1933, 1946, 1974, 1992, 2005, 2033, 2052,\n", - " 2053, 2062, 2069, 2073, 2074, 2089, 2091, 2094, 2103, 2113, 2116,\n", - " 2122, 2127, 2135, 2149, 2154, 2162, 2164, 2166, 2180, 2181, 2182,\n", - " 2209, 2211, 2245, 2253, 2257, 2268, 2271, 2288, 2290, 2296, 2316,\n", - " 2334, 2337, 2338, 2339, 2341, 2347, 2349, 2351, 2355, 2356, 2405,\n", - " 2413, 2422, 2428, 2438, 2440, 2448, 2455, 2464, 2473, 2479, 2482,\n", - " 2490, 2509, 2517, 2531, 2550, 2555, 2558, 2574, 2575, 2583, 2589,\n", - " 2591, 2597, 2611, 2614, 2618, 2627, 2633, 2636, 2643, 2682, 2700,\n", - " 2704, 2707, 2716, 2721, 2726, 2754, 2764, 2765, 2793, 2794, 2805,\n", - " 2814, 2835, 2852, 2855, 2856, 2862, 2866, 2878, 2891, 2909, 2918,\n", - " 2920, 2924, 2974, 2982, 2993, 3011, 3020, 3022, 3040, 3041, 3044,\n", - " 3054, 3056, 3091, 3101, 3107, 3108, 3111, 3142, 3151, 3156, 3203,\n", - " 3206, 3213, 3217, 3231, 3269, 3309, 3313, 3331, 3332, 3335, 3342,\n", - " 3349, 3359, 3374, 3389, 3400, 3403, 3445, 3453, 3460, 3467, 3492,\n", - " 3498, 3500, 3515, 3521, 3525, 3526, 3529, 3543, 3568, 3571, 3585,\n", - " 3588, 3589, 3591, 3594, 3604]))" - ] - }, - "execution_count": 104, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ - "d" + "synth_hh" ] }, { @@ -5497,14 +1951,31 @@ "execution_count": null, "metadata": {}, "outputs": [], - "source": [] + "source": [ + "mrg_tbl = pd.DataFrame(\n", + " {'serialno': synth_hh.serialno.values,\n", + " 'hh_id': synth_hh.index.values})" + ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], - "source": [] + "source": [ + "mrg_tbl" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Finally, synthetic persons dataset will be built based on `p_pums` and the `hh_id` of synthetic households. As follows: \n", + "\n", + "```\n", + "synth_people = pd.merge(p_pums, mrg_tbl, left_on='serialno', right_on='serialno')\n", + "```" + ] } ], "metadata": { From 96bbc334cf2414b4dc093d83508b0832389d3be4 Mon Sep 17 00:00:00 2001 From: PyMap Date: Tue, 28 Jul 2020 19:20:02 -0300 Subject: [PATCH 12/12] draw --- demos/Synthesis workflow.ipynb | 5848 +++++++++++++++++++++++++++----- 1 file changed, 5022 insertions(+), 826 deletions(-) diff --git a/demos/Synthesis workflow.ipynb b/demos/Synthesis workflow.ipynb index 69ffaaf..b5b8b2e 100644 --- a/demos/Synthesis workflow.ipynb +++ b/demos/Synthesis workflow.ipynb @@ -463,7 +463,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 7, "metadata": {}, "outputs": [], "source": [ @@ -473,9 +473,17 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 8, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "['acsyear', 'c', 'county', 'get_available_geography_ids', 'get_geography_name', 'get_household_joint_dist_for_geography', 'get_household_marginal_for_geography', 'get_num_geographies', 'get_person_joint_dist_for_geography', 'get_person_marginal_for_geography', 'h_acs', 'h_acs_cat', 'h_pums_cols', 'p_acs', 'p_acs_cat', 'p_pums_cols', 'state', 'tract']\n" + ] + } + ], "source": [ "# what do we get from starter class?\n", "print([m for m in dir(starter) if not m.startswith('__')])" @@ -490,9 +498,20 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 9, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "('02', '290')" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "# ...state and county pair\n", "starter.state, starter.county" @@ -521,16 +540,143 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 10, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
NAMEB19001_001EB19001_002EB19001_003EB19001_004EB19001_005EB19001_006EB19001_007EB19001_008EB19001_009E...B08201_002EB08201_003EB08201_004EB08201_005EB08201_006EB08202_001EB08202_002EB08202_003EB08202_004EB08202_005E
0Block Group 1, Census Tract 1, Yukon-Koyukuk C...187521320112012118...1194016371878974212
1Block Group 2, Census Tract 1, Yukon-Koyukuk C...33668194220112789...2147130513336160133373
\n", + "

2 rows × 127 columns

\n", + "
" + ], + "text/plain": [ + " NAME B19001_001E \\\n", + "0 Block Group 1, Census Tract 1, Yukon-Koyukuk C... 187 \n", + "1 Block Group 2, Census Tract 1, Yukon-Koyukuk C... 336 \n", + "\n", + " B19001_002E B19001_003E B19001_004E B19001_005E B19001_006E \\\n", + "0 52 13 20 11 20 \n", + "1 68 19 42 20 11 \n", + "\n", + " B19001_007E B19001_008E B19001_009E ... B08201_002E B08201_003E \\\n", + "0 12 1 18 ... 119 40 \n", + "1 27 8 9 ... 214 71 \n", + "\n", + " B08201_004E B08201_005E B08201_006E B08202_001E B08202_002E \\\n", + "0 16 3 7 187 89 \n", + "1 30 5 13 336 160 \n", + "\n", + " B08202_003E B08202_004E B08202_005E \n", + "0 74 21 2 \n", + "1 133 37 3 \n", + "\n", + "[2 rows x 127 columns]" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "starter.h_acs.head(2)" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 11, "metadata": {}, "outputs": [], "source": [ @@ -540,27 +686,57 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 12, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "starter.c " ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 13, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "c" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 14, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "['_get_fips_lookup', '_get_pums_relationship', '_query', '_read_csv', '_scale_and_merge', 'acsyear_files', 'base_url', 'block_group_and_tract_query', 'block_group_query', 'c', 'download_household_pums', 'download_population_pums', 'fips_df', 'fips_url', 'pums00_household_base_url', 'pums00_population_base_url', 'pums10_household_base_url', 'pums10_population_base_url', 'pums_cache', 'pums_household_state_base_url', 'pums_population_state_base_url', 'pums_relationship_df', 'pums_relationship_file_url', 'tract_query', 'tract_to_puma', 'try_fips_lookup']\n" + ] + } + ], "source": [ "# that has his own methods \n", "print([ m for m in dir(c) if not m.startswith('__')])" @@ -577,9 +753,20 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 15, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + ">" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "# we create and merge both tables with:\n", "c.block_group_and_tract_query" @@ -596,9 +783,17 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 16, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "['ALL', '_acs', 'acs', 'acs1', 'acs1dp', 'acs3', 'acs3dp', 'acs5', 'acs5dp', 'session', 'sf1', 'sf3']\n" + ] + } + ], "source": [ "# imported methods from census module\n", "print([ m for m in dir(c.c) if not m.startswith('__')])" @@ -613,7 +808,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 17, "metadata": {}, "outputs": [], "source": [ @@ -628,7 +823,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 18, "metadata": {}, "outputs": [], "source": [ @@ -639,16 +834,110 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 19, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
NAMEB11005_001EB11005_002EB11005_011Estatecountytract
0Census Tract 1, Yukon-Koyukuk Census Area, Alaska523140.0383.002290000100
1Census Tract 2, Yukon-Koyukuk Census Area, Alaska549155.0394.002290000200
2Census Tract 3, Yukon-Koyukuk Census Area, Alaska612251.0361.002290000300
3Census Tract 4, Yukon-Koyukuk Census Area, Alaska372151.0221.002290000400
\n", + "
" + ], + "text/plain": [ + " NAME B11005_001E B11005_002E \\\n", + "0 Census Tract 1, Yukon-Koyukuk Census Area, Alaska 523 140.0 \n", + "1 Census Tract 2, Yukon-Koyukuk Census Area, Alaska 549 155.0 \n", + "2 Census Tract 3, Yukon-Koyukuk Census Area, Alaska 612 251.0 \n", + "3 Census Tract 4, Yukon-Koyukuk Census Area, Alaska 372 151.0 \n", + "\n", + " B11005_011E state county tract \n", + "0 383.0 02 290 000100 \n", + "1 394.0 02 290 000200 \n", + "2 361.0 02 290 000300 \n", + "3 221.0 02 290 000400 " + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "pd.DataFrame(tr)" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 20, "metadata": {}, "outputs": [], "source": [ @@ -659,761 +948,1792 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "pd.DataFrame(bg)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Both tables are merged at the highest disaggregation level (block group). To do it `scale and merge` Census method scales down from tract to block group level as it is shown below:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# tract variables\n", - "starter.h_acs[['NAME']+vehicle_columns]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Finally, we build the `acs` table for block group and tracts levels - this process is repeated for persons too, here we only demo households subject tables-." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# the None tract value correspond to all the tracts\n", - "h_acs = c.block_group_and_tract_query(block_group_columns=presence_of_children_columns,\n", - " tract_columns=vehicle_columns, \n", - " state='02', county='290',\n", - " merge_columns=['tract', 'county', 'state'],\n", - " block_group_size_attr=\"B11005_001E\",\n", - " tract_size_attr=\"B08201_001E\",\n", - " tract=None, year=2013)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "h_acs.head(2)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 2.2. `Categorize` subject tables " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Once we get the subject data for [households](https://github.com/UDST/synthpop/blob/0bc36f8fef036913b416e0d4eb8a3fda79fc70ad/synthpop/recipes/starter2.py#L52-L68) and [persons](https://github.com/UDST/synthpop/blob/0bc36f8fef036913b416e0d4eb8a3fda79fc70ad/synthpop/recipes/starter2.py#L131-L139) variables, the `acs` dataset is categorized by: " - ] - }, - { - "cell_type": "code", - "execution_count": null, + "execution_count": 21, "metadata": {}, - "outputs": [], - "source": [ - "from synthpop import categorizer as cat" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
NAMEB11005_001EB11005_002EB11005_011Estatecountytractblock group
0Block Group 1, Census Tract 1, Yukon-Koyukuk C...18758.0129.0022900001001
1Block Group 2, Census Tract 1, Yukon-Koyukuk C...33682.0254.0022900001002
2Block Group 1, Census Tract 2, Yukon-Koyukuk C...20857.0151.0022900002001
3Block Group 2, Census Tract 2, Yukon-Koyukuk C...34198.0243.0022900002002
4Block Group 1, Census Tract 3, Yukon-Koyukuk C...234108.0126.0022900003001
5Block Group 2, Census Tract 3, Yukon-Koyukuk C...19076.0114.0022900003002
6Block Group 3, Census Tract 3, Yukon-Koyukuk C...18867.0121.0022900003003
7Block Group 1, Census Tract 4, Yukon-Koyukuk C...18082.098.0022900004001
8Block Group 2, Census Tract 4, Yukon-Koyukuk C...19269.0123.0022900004002
\n", + "
" + ], + "text/plain": [ + " NAME B11005_001E B11005_002E \\\n", + "0 Block Group 1, Census Tract 1, Yukon-Koyukuk C... 187 58.0 \n", + "1 Block Group 2, Census Tract 1, Yukon-Koyukuk C... 336 82.0 \n", + "2 Block Group 1, Census Tract 2, Yukon-Koyukuk C... 208 57.0 \n", + "3 Block Group 2, Census Tract 2, Yukon-Koyukuk C... 341 98.0 \n", + "4 Block Group 1, Census Tract 3, Yukon-Koyukuk C... 234 108.0 \n", + "5 Block Group 2, Census Tract 3, Yukon-Koyukuk C... 190 76.0 \n", + "6 Block Group 3, Census Tract 3, Yukon-Koyukuk C... 188 67.0 \n", + "7 Block Group 1, Census Tract 4, Yukon-Koyukuk C... 180 82.0 \n", + "8 Block Group 2, Census Tract 4, Yukon-Koyukuk C... 192 69.0 \n", + "\n", + " B11005_011E state county tract block group \n", + "0 129.0 02 290 000100 1 \n", + "1 254.0 02 290 000100 2 \n", + "2 151.0 02 290 000200 1 \n", + "3 243.0 02 290 000200 2 \n", + "4 126.0 02 290 000300 1 \n", + "5 114.0 02 290 000300 2 \n", + "6 121.0 02 290 000300 3 \n", + "7 98.0 02 290 000400 1 \n", + "8 123.0 02 290 000400 2 " + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "cat.categorize" + "pd.DataFrame(bg)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "This give us back a multindexed table with new names:" + "Both tables are merged at the highest disaggregation level (block group). To do it `scale and merge` Census method scales down from tract to block group level as it is shown below:" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 22, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
NAMEB08201_001EB08201_002EB08201_003EB08201_004EB08201_005EB08201_006E
0Block Group 1, Census Tract 1, Yukon-Koyukuk C...187119401637
1Block Group 2, Census Tract 1, Yukon-Koyukuk C...3362147130513
2Block Group 1, Census Tract 2, Yukon-Koyukuk C...2085173502111
3Block Group 2, Census Tract 2, Yukon-Koyukuk C...34183120833418
4Block Group 1, Census Tract 3, Yukon-Koyukuk C...234127583584
5Block Group 2, Census Tract 3, Yukon-Koyukuk C...190103472873
6Block Group 3, Census Tract 3, Yukon-Koyukuk C...188102462873
7Block Group 1, Census Tract 4, Yukon-Koyukuk C...18091463252
8Block Group 2, Census Tract 4, Yukon-Koyukuk C...19298503553
\n", + "
" + ], + "text/plain": [ + " NAME B08201_001E \\\n", + "0 Block Group 1, Census Tract 1, Yukon-Koyukuk C... 187 \n", + "1 Block Group 2, Census Tract 1, Yukon-Koyukuk C... 336 \n", + "2 Block Group 1, Census Tract 2, Yukon-Koyukuk C... 208 \n", + "3 Block Group 2, Census Tract 2, Yukon-Koyukuk C... 341 \n", + "4 Block Group 1, Census Tract 3, Yukon-Koyukuk C... 234 \n", + "5 Block Group 2, Census Tract 3, Yukon-Koyukuk C... 190 \n", + "6 Block Group 3, Census Tract 3, Yukon-Koyukuk C... 188 \n", + "7 Block Group 1, Census Tract 4, Yukon-Koyukuk C... 180 \n", + "8 Block Group 2, Census Tract 4, Yukon-Koyukuk C... 192 \n", + "\n", + " B08201_002E B08201_003E B08201_004E B08201_005E B08201_006E \n", + "0 119 40 16 3 7 \n", + "1 214 71 30 5 13 \n", + "2 51 73 50 21 11 \n", + "3 83 120 83 34 18 \n", + "4 127 58 35 8 4 \n", + "5 103 47 28 7 3 \n", + "6 102 46 28 7 3 \n", + "7 91 46 32 5 2 \n", + "8 98 50 35 5 3 " + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "h_acs_cat = cat.categorize(h_acs, {(\"hh_children\", \"yes\"): \"B11005_002E\",\n", - " (\"hh_children\", \"no\"): \"B11005_011E\",\n", - " (\"hh_cars\", \"none\"): \"B08201_002E\",\n", - " (\"hh_cars\", \"one\"): \"B08201_003E\",\n", - " (\"hh_cars\", \"two or more\"):\n", - " \"B08201_004E + B08201_005E + B08201_006E\"},\n", - " index_cols=['state', 'county', 'tract', 'block group'])" + "# tract variables\n", + "starter.h_acs[['NAME']+vehicle_columns]" ] }, { - "cell_type": "code", - "execution_count": null, + "cell_type": "markdown", "metadata": {}, - "outputs": [], "source": [ - "h_acs_cat" + "Finally, we build the `acs` table for block group and tracts levels - this process is repeated for persons too, here we only demo households subject tables-." ] }, { - "cell_type": "markdown", + "cell_type": "code", + "execution_count": 23, "metadata": {}, + "outputs": [], "source": [ - "... that can also be obtained by calling it from the `starter` object:" + "# the None tract value correspond to all the tracts\n", + "h_acs = c.block_group_and_tract_query(block_group_columns=presence_of_children_columns,\n", + " tract_columns=vehicle_columns, \n", + " state='02', county='290',\n", + " merge_columns=['tract', 'county', 'state'],\n", + " block_group_size_attr=\"B11005_001E\",\n", + " tract_size_attr=\"B08201_001E\",\n", + " tract=None, year=2013)" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 24, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
NAMEB11005_001EB11005_002EB11005_011Estatecountytractblock groupB08201_001EB08201_002EB08201_003EB08201_004EB08201_005EB08201_006E
0Block Group 1, Census Tract 1, Yukon-Koyukuk C...18758129022900001001187119401637
1Block Group 2, Census Tract 1, Yukon-Koyukuk C...336822540229000010023362147130513
\n", + "
" + ], + "text/plain": [ + " NAME B11005_001E \\\n", + "0 Block Group 1, Census Tract 1, Yukon-Koyukuk C... 187 \n", + "1 Block Group 2, Census Tract 1, Yukon-Koyukuk C... 336 \n", + "\n", + " B11005_002E B11005_011E state county tract block group B08201_001E \\\n", + "0 58 129 02 290 000100 1 187 \n", + "1 82 254 02 290 000100 2 336 \n", + "\n", + " B08201_002E B08201_003E B08201_004E B08201_005E B08201_006E \n", + "0 119 40 16 3 7 \n", + "1 214 71 30 5 13 " + ] + }, + "execution_count": 24, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "# here the entire table built in starter2\n", - "starter.h_acs_cat" + "h_acs.head(2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "### 2.3. Geography relations for joint distributions" + "### 2.2. `Categorize` subject tables " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "![pums](img/download_pums.png)" + "Once we get the subject data for [households](https://github.com/UDST/synthpop/blob/0bc36f8fef036913b416e0d4eb8a3fda79fc70ad/synthpop/recipes/starter2.py#L52-L68) and [persons](https://github.com/UDST/synthpop/blob/0bc36f8fef036913b416e0d4eb8a3fda79fc70ad/synthpop/recipes/starter2.py#L131-L139) variables, the `acs` dataset is categorized by: " ] }, { - "cell_type": "markdown", + "cell_type": "code", + "execution_count": 25, "metadata": {}, + "outputs": [], "source": [ - "As we can see in the diagram, one important method from `Census` constructor is the:" + "from synthpop import categorizer as cat" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 26, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "c.tract_to_puma" + "cat.categorize" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "... which returns the correspondant puma id for a given tract:" + "This give us back a multindexed table with new names:" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 27, "metadata": {}, "outputs": [], "source": [ - "for tract in ['000100','000200','000300','000400']:\n", - " print('puma10 id for tract {} : {}'.format(tract, c.tract_to_puma(state, county, tract)[0]))\n", - " print('puma00 id for tract {} : {}'.format(tract, c.tract_to_puma(state, county, tract)[1]))\n", - " puma10, puma00 = c.tract_to_puma(state, county, tract)" + "h_acs_cat = cat.categorize(h_acs, {(\"hh_children\", \"yes\"): \"B11005_002E\",\n", + " (\"hh_children\", \"no\"): \"B11005_011E\",\n", + " (\"hh_cars\", \"none\"): \"B08201_002E\",\n", + " (\"hh_cars\", \"one\"): \"B08201_003E\",\n", + " (\"hh_cars\", \"two or more\"):\n", + " \"B08201_004E + B08201_005E + B08201_006E\"},\n", + " index_cols=['state', 'county', 'tract', 'block group'])" ] }, { - "cell_type": "markdown", + "cell_type": "code", + "execution_count": 28, "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
cat_namehh_carshh_children
cat_valuenoneonetwo or morenoyes
statecountytractblock group
022900001001119402612958
2214714825482
000200151738215157
28312013524398
00030011275847126108
2103473811476
3102463812167
00040019146399882
298504312369
\n", + "
" + ], + "text/plain": [ + "cat_name hh_cars hh_children \n", + "cat_value none one two or more no yes\n", + "state county tract block group \n", + "02 290 000100 1 119 40 26 129 58\n", + " 2 214 71 48 254 82\n", + " 000200 1 51 73 82 151 57\n", + " 2 83 120 135 243 98\n", + " 000300 1 127 58 47 126 108\n", + " 2 103 47 38 114 76\n", + " 3 102 46 38 121 67\n", + " 000400 1 91 46 39 98 82\n", + " 2 98 50 43 123 69" + ] + }, + "execution_count": 28, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "This information will be mainly used to download `pums` from `aws` or `gcs` (depending on the acs requested year)." + "h_acs_cat" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "##### What we call slices?: the `PUMA` geographies " + "... that can also be obtained by calling it from the `starter` object:" ] }, { - "cell_type": "markdown", + "cell_type": "code", + "execution_count": 29, "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
cat_namehh_age_of_headhh_carshh_childrenhh_income...hispanic_headseniorssf_detachedtenure_mover
cat_valuegt35-lt65gt65lt35noneonetwo or morenoyesgt100-lt150gt150...noyesnoyesnoyesown not recentown recentrent not recentrent recent
statecountytractblock group
022900001001122254011940261295860...187016225018713593112
221077492147148254823315...33152597720316222104658
000200112367185173821515782...2044138701519314744512
2229763683120135243985925...33922548744297240116921
00030011464345127584712610891...234018450123315094728
212144251034738114764116...1882143476184129132919
3112373910246381216780...188014741418413523318
0004001924939914639988237...180013149018012164211
2108463898504312369166...18841444871859786918
\n", + "

9 rows × 34 columns

\n", + "
" + ], + "text/plain": [ + "cat_name hh_age_of_head hh_cars \\\n", + "cat_value gt35-lt65 gt65 lt35 none one \n", + "state county tract block group \n", + "02 290 000100 1 122 25 40 119 40 \n", + " 2 210 77 49 214 71 \n", + " 000200 1 123 67 18 51 73 \n", + " 2 229 76 36 83 120 \n", + " 000300 1 146 43 45 127 58 \n", + " 2 121 44 25 103 47 \n", + " 3 112 37 39 102 46 \n", + " 000400 1 92 49 39 91 46 \n", + " 2 108 46 38 98 50 \n", + "\n", + "cat_name hh_children hh_income \\\n", + "cat_value two or more no yes gt100-lt150 \n", + "state county tract block group \n", + "02 290 000100 1 26 129 58 6 \n", + " 2 48 254 82 33 \n", + " 000200 1 82 151 57 8 \n", + " 2 135 243 98 59 \n", + " 000300 1 47 126 108 9 \n", + " 2 38 114 76 41 \n", + " 3 38 121 67 8 \n", + " 000400 1 39 98 82 3 \n", + " 2 43 123 69 16 \n", + "\n", + "cat_name ... hispanic_head seniors \\\n", + "cat_value gt150 ... no yes no yes \n", + "state county tract block group ... \n", + "02 290 000100 1 0 ... 187 0 162 25 \n", + " 2 15 ... 331 5 259 77 \n", + " 000200 1 2 ... 204 4 138 70 \n", + " 2 25 ... 339 2 254 87 \n", + " 000300 1 1 ... 234 0 184 50 \n", + " 2 16 ... 188 2 143 47 \n", + " 3 0 ... 188 0 147 41 \n", + " 000400 1 7 ... 180 0 131 49 \n", + " 2 6 ... 188 4 144 48 \n", + "\n", + "cat_name sf_detached tenure_mover \\\n", + "cat_value no yes own not recent own recent \n", + "state county tract block group \n", + "02 290 000100 1 0 187 135 9 \n", + " 2 20 316 222 10 \n", + " 000200 1 15 193 147 4 \n", + " 2 44 297 240 11 \n", + " 000300 1 1 233 150 9 \n", + " 2 6 184 129 13 \n", + " 3 4 184 135 2 \n", + " 000400 1 0 180 121 6 \n", + " 2 7 185 97 8 \n", + "\n", + "cat_name \n", + "cat_value rent not recent rent recent \n", + "state county tract block group \n", + "02 290 000100 1 31 12 \n", + " 2 46 58 \n", + " 000200 1 45 12 \n", + " 2 69 21 \n", + " 000300 1 47 28 \n", + " 2 29 19 \n", + " 3 33 18 \n", + " 000400 1 42 11 \n", + " 2 69 18 \n", + "\n", + "[9 rows x 34 columns]" + ] + }, + "execution_count": 29, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "![pums_rel](img/pums_tracts.png)" + "# here the entire table built in starter2\n", + "starter.h_acs_cat" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "PUMS stands for Public Use Microdata Sample. These are individual records of survey responses with identifying\n", - "information removed.These files do not include every record of every person who responded to the ACS. Only a select few that in turn, are representative of the population. \n", - "\n", - "The ACS samples 3.5 million addresses per year. The 1-year ACS PUMS file contains about 1% of all of the US households. The 5-year ACS PUMS file is the equivalent of five 1-year files, so it includes about 5% of all of the US households.\n", - "\n", - "By contrast, in aggregated tables or summary data, the individual records are categorized and weighted to create an estimate for the larger population. These estimates contains a Margin of Error (which is, to put it into simple words, the percentage of times we do not hit a target population type when we randomly select cases: e.g. 5%, etc. ).\n", - "\n", - "This means that, since `PUMS` microdata provides a sample of the ACS records it is necessary to create an estimate of how many persons/households the raw records represent. This microdata has no geographies smaller than what we call `PUMAs`.\n", - "\n", - "PUMA is an area where the population of over 100,000 in – population of over 100,000, large enough to meet the disclosure avoidance requirements. It is identified by a five-digit code that is unique within each estate, and they nest within state or state equivalence.\n", - "\n", - "PUMAs are redefined after each Decennial Census. It is important to mention that PUMAs redefined after the 2010 Census were first used in 2012 ACS PUMS files. Multi-year files contain dual PUMAs vintages, for example, the 2010 to 2014 ACS PUMS files. PUMAs are built on Census Tracks and Counties, and can be combined to create rough approximations of towns, counties or cities for analysis." + "### 2.3. Geography relations for joint distributions" ] }, { - "cell_type": "code", - "execution_count": null, + "cell_type": "markdown", "metadata": {}, - "outputs": [], "source": [ - "# PUMS variables\n", - "h_pums_cols = ('serialno', 'PUMA00','PUMA10', 'RT', 'NP', 'TYPE',\n", - " 'R65', 'HINCP', 'VEH', 'MV', 'TEN', 'BLD', 'R18')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "h_pums = c.download_household_pums(state, puma10, puma00, usecols=h_pums_cols)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "h_pums" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "##### Using `PUMS` files" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Joint distributions represents a total value for acs queried table. Since this last dataset contains aggregated data for tracts and block groups levels, and given that the PUMS are a representative sample of individual records - each serial number corresponds to a unique answer -, both tables will be used to build target values to be joined during the synthesis. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "cat.joint_distribution" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "First, we build a dataframe with the target categories that we obtained querying the `acs subject table`. This, by calling the `category_combinations` method from the categorizer that will return all possible combinations: " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "cat.category_combinations(h_acs_cat.columns)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "With this, the `joint_distribution` method will return a sample and categories dataframes. This by following next steps:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# mapping functions to return values depending on slices dataframes\n", - "def cars_cat(r):\n", - " if r.VEH == 0:\n", - " return \"none\"\n", - " elif r.VEH == 1:\n", - " return \"one\"\n", - " return \"two or more\"\n", - "\n", - "def children_cat(r):\n", - " if r.R18 == 1:\n", - " return \"yes\"\n", - " return \"no\"" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "h_pums, jd_households = cat.joint_distribution(h_pums,\n", - " cat.category_combinations(h_acs_cat.columns),\n", - " {\"hh_cars\": cars_cat,\n", - " \"hh_children\": children_cat,\n", - " })" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "- **1. Categories dataframe**\n", - "\n", - "This cointains the amount of cases (or frequencies) for each category combination within the PUMA geography. It is important to remark that this totals corresponds to all the tracts we passed to the `tract to puma` function. Given that PUMS returns individual answers for a bunch of variables, we can combine them based on acs subject table columns and get the totals of each combination for a group tracts. This will return a total value for a group of tracts (or PUMA). PUMAs are unique whitin a state." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "jd_households" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "- **2. Sample dataframe**\n", - "\n", - "This is the microdata puma df we downloaded for tracts 100 to 400, with a new `cat_id` combination column:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "h_pums" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Until this point, we...**:\n", - "1. Queried the `acs5` subject table to get persons and households variables at block group and tracts levels\n", - "2. Downloaded sample files (PUMS) containing the same variables with different standard names.\n", - "3. Matched the tracts of the `county`, `state` pair with a puma id.\n", - "4. Built combination of variables at puma level - or all the tracts that are cointained inside a puma id (e.g. households with no children and no cars)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 2.4. Marginals, the block group level" + "![pums](img/download_pums.png)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "Marginals are called from the `starter` object inside the `synthesize_all` function and returns..." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "#...for a group of available geographies inside a county/state pair\n", - "list(starter.get_available_geography_ids())[0]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "indexes = starter.get_available_geography_ids()" + "As we can see in the diagram, one important method from `Census` constructor is the:" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 30, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + ">" + ] + }, + "execution_count": 30, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "for geog_id in indexes:\n", - " h_marg = starter.get_household_marginal_for_geography(geog_id)" + "c.tract_to_puma" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "***...the total value of a given variable for the block group geography levels:***" + "... which returns the correspondant puma id for a given tract:" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 31, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "puma10 id for tract 000100 : 00400\n", + "puma00 id for tract 000100 : 00400\n", + "puma10 id for tract 000200 : 00400\n", + "puma00 id for tract 000200 : 00400\n", + "puma10 id for tract 000300 : 00400\n", + "puma00 id for tract 000300 : 00400\n", + "puma10 id for tract 000400 : 00400\n", + "puma00 id for tract 000400 : 00400\n" + ] + } + ], "source": [ - "# This is the marginal table we stored for the last census tract (400)\n", - "h_marg" + "for tract in ['000100','000200','000300','000400']:\n", + " print('puma10 id for tract {} : {}'.format(tract, c.tract_to_puma(state, county, tract)[0]))\n", + " print('puma00 id for tract {} : {}'.format(tract, c.tract_to_puma(state, county, tract)[1]))\n", + " puma10, puma00 = c.tract_to_puma(state, county, tract)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "For example, in our acs5 categorized table, in the block group 1 of the 000400 tract (we only stored the last geography since we ran a for loop) there are 82 households with childs and 46 with one car." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# can check these totals in our acs subject table...\n", - "h_acs_cat" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# store the marginal values from the block group 1 of the 000400 census tract\n", - "hh_marginals_tract_400_block_gp_1 = h_acs_cat.loc[tuple(list(starter.get_available_geography_ids())[7])]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "hh_marginals_tract_400_block_gp_1" + "This information will be mainly used to download `pums` from `aws` or `gcs` (depending on the acs requested year)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "## 3. Sinthesize all: using `Starter` outputs " + "##### What we call slices?: the `PUMA` geographies " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "### 3.1 The iterative proportional fitting (IPF) procedure " + "![pums_rel](img/pums_tracts.png)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "![constraints](img/constraints.png)" + "PUMS stands for Public Use Microdata Sample. These are individual records of survey responses with identifying\n", + "information removed.These files do not include every record of every person who responded to the ACS. Only a select few that in turn, are representative of the population. \n", + "\n", + "The ACS samples 3.5 million addresses per year. The 1-year ACS PUMS file contains about 1% of all of the US households. The 5-year ACS PUMS file is the equivalent of five 1-year files, so it includes about 5% of all of the US households.\n", + "\n", + "By contrast, in aggregated tables or summary data, the individual records are categorized and weighted to create an estimate for the larger population. These estimates contains a Margin of Error (which is, to put it into simple words, the percentage of times we do not hit a target population type when we randomly select cases: e.g. 5%, etc. ).\n", + "\n", + "This means that, since `PUMS` microdata provides a sample of the ACS records it is necessary to create an estimate of how many persons/households the raw records represent. This microdata has no geographies smaller than what we call `PUMAs`.\n", + "\n", + "PUMA is an area where the population of over 100,000 in – population of over 100,000, large enough to meet the disclosure avoidance requirements. It is identified by a five-digit code that is unique within each estate, and they nest within state or state equivalence.\n", + "\n", + "PUMAs are redefined after each Decennial Census. It is important to mention that PUMAs redefined after the 2010 Census were first used in 2012 ACS PUMS files. Multi-year files contain dual PUMAs vintages, for example, the 2010 to 2014 ACS PUMS files. PUMAs are built on Census Tracks and Counties, and can be combined to create rough approximations of towns, counties or cities for analysis." ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 32, "metadata": {}, "outputs": [], "source": [ - "from synthpop.ipf.ipf import calculate_constraints" + "# PUMS variables\n", + "h_pums_cols = ('serialno', 'PUMA00','PUMA10', 'RT', 'NP', 'TYPE',\n", + " 'R65', 'HINCP', 'VEH', 'MV', 'TEN', 'BLD', 'R18')" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 33, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Downloading households pums from https://s3-us-west-1.amazonaws.com/synthpop-data2/\n", + "Reading PUMS00 from https://s3-us-west-1.amazonaws.com/synthpop-data2/\n" + ] + } + ], "source": [ - "h_constraint, _ = calculate_constraints(hh_marginals_tract_400_block_gp_1, jd_households.frequency)" + "h_pums = c.download_household_pums(state, puma10, puma00, usecols=h_pums_cols)" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 34, "metadata": {}, - "outputs": [], - "source": [ - "# this is our contraints table\n", - "h_constraint" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
serialnoRTpuma00puma10NPTYPEBLDTENVEHHINCPMVR18R65
02012000000643H-9400212.03.00.033360.01.00.00.0
22012000001889H-9400412.02.00.089420.07.00.02.0
32012000003083H-9400112.02.00.020800.07.00.00.0
42012000004753H-9400712.02.00.026300.06.01.00.0
52012000005450H-9400313.03.01.065300.01.01.00.0
..........................................
58572011001481195H400-9612.03.01.0165600.07.01.01.0
58582011001486432H400-9512.02.00.023900.05.01.00.0
58622011001495660H400-9312.02.02.029500.07.00.02.0
58652011001496296H400-9112.04.00.0900.07.00.00.0
58682011001498413H400-9412.03.01.019600.02.01.00.0
\n", + "

3625 rows × 13 columns

\n", + "
" + ], + "text/plain": [ + " serialno RT puma00 puma10 NP TYPE BLD TEN VEH HINCP MV \\\n", + "0 2012000000643 H -9 400 2 1 2.0 3.0 0.0 33360.0 1.0 \n", + "2 2012000001889 H -9 400 4 1 2.0 2.0 0.0 89420.0 7.0 \n", + "3 2012000003083 H -9 400 1 1 2.0 2.0 0.0 20800.0 7.0 \n", + "4 2012000004753 H -9 400 7 1 2.0 2.0 0.0 26300.0 6.0 \n", + "5 2012000005450 H -9 400 3 1 3.0 3.0 1.0 65300.0 1.0 \n", + "... ... .. ... ... .. ... ... ... ... ... ... \n", + "5857 2011001481195 H 400 -9 6 1 2.0 3.0 1.0 165600.0 7.0 \n", + "5858 2011001486432 H 400 -9 5 1 2.0 2.0 0.0 23900.0 5.0 \n", + "5862 2011001495660 H 400 -9 3 1 2.0 2.0 2.0 29500.0 7.0 \n", + "5865 2011001496296 H 400 -9 1 1 2.0 4.0 0.0 900.0 7.0 \n", + "5868 2011001498413 H 400 -9 4 1 2.0 3.0 1.0 19600.0 2.0 \n", + "\n", + " R18 R65 \n", + "0 0.0 0.0 \n", + "2 0.0 2.0 \n", + "3 0.0 0.0 \n", + "4 1.0 0.0 \n", + "5 1.0 0.0 \n", + "... ... ... \n", + "5857 1.0 1.0 \n", + "5858 1.0 0.0 \n", + "5862 0.0 2.0 \n", + "5865 0.0 0.0 \n", + "5868 1.0 0.0 \n", + "\n", + "[3625 rows x 13 columns]" + ] + }, + "execution_count": 34, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "# this is the number of iterations performed to achieve the constraint values\n", - "_" + "h_pums" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "In the block group 1 of the census tract 400 we used to have 91 households with no cars, 46 with one car and 39 with two or more:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "bg_targets = hh_marginals_tract_400_block_gp_1[:3]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "bg_targets" + "##### Using `PUMS` files" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "At the same time, our `joint_distributions` table gave us the total of that variable for the entire PUMA (in this case, `843 households with no children + 919 households with one children = 1762 households with no cars`:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "jd_households[:2]" + "Joint distributions represents a total value for acs queried table. Since this last dataset contains aggregated data for tracts and block groups levels, and given that the PUMS are a representative sample of individual records - each serial number corresponds to a unique answer -, both tables will be used to build target values to be joined during the synthesis. " ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 35, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 35, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "jd_households['frequency'][:2].sum()" + "cat.joint_distribution" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "With this information, we will build new target values for each category total within the block group by multiplying the target and the proportion that this target represents in the entire PUMA - remember here, that our joint distribution table gets this total by combining different variables. In our case number of cars and children -\n", - "\n", - "`new_target = current_target * (proportion of the current target)`" + "First, we build a dataframe with the target categories that we obtained querying the `acs subject table`. This, by calling the `category_combinations` method from the categorizer that will return all possible combinations: " ] }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "sub_category_idx_0 = 0\n", - "sub_category_idx_1 = 2\n", - "\n", - "for target in range(len(bg_targets)):\n", - " total_cat = jd_households.frequency[sub_category_idx_0:sub_category_idx_1].sum()\n", - " sub_category_idx_0 += 2\n", - " sub_category_idx_1 += 2\n", - " print('Block group target value: %s'%str(bg_targets[target]))\n", - " print('Total value of the combined category is: %s'%str(total_cat))\n", - " print('Proportion of each category in the combined variables total: %s'%str(bg_targets[target] / total_cat))\n", - " print('New Block group target value: %s'%str(bg_targets[target]*(bg_targets[target] / total_cat)))\n", - " print('*********************************************************************************')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "These new values that were built based on the proportion that each block group represents in the PUMA (for every category value) will be used to update our joint distributions table: " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "jd_households.values" - ] - }, - { - "cell_type": "markdown", + "execution_count": 36, "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
cat_id
hh_carshh_children
noneno0
yes1
oneno2
yes3
two or moreno4
yes5
\n", + "
" + ], + "text/plain": [ + " cat_id\n", + "hh_cars hh_children \n", + "none no 0\n", + " yes 1\n", + "one no 2\n", + " yes 3\n", + "two or more no 4\n", + " yes 5" + ] + }, + "execution_count": 36, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "...the totals we had for each `category combination`: 0; 1; 2; 3; 4 & 5 will be replaced using that proportion. This way we will define a new maximum value for every category within the block group." + "cat.category_combinations(h_acs_cat.columns)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "Imagine we have a constraints table with categories from 0 to 2 (has no car and no children, has no car but children and has one car and no children) as we shown in the example above. We will need to:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "current_constraints = jd_households[:3].values.copy()" + "With this, the `joint_distribution` method will return a sample and categories dataframes. This by following next steps:" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 37, "metadata": {}, "outputs": [], "source": [ - "# 1. define new targets based on proportions\n", - "new_targets = [4.69977298524404, 2.1075697211155378, 1.7706635622817228]\n", + "# mapping functions to return values depending on slices dataframes\n", + "def cars_cat(r):\n", + " if r.VEH == 0:\n", + " return \"none\"\n", + " elif r.VEH == 1:\n", + " return \"one\"\n", + " return \"two or more\"\n", "\n", - "next_constraints = current_constraints.astype(float)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# 2. update the constraints table\n", - "fre = -1\n", - "for t in new_targets:\n", - " fre +=1 \n", - " next_constraints[fre][1] = t" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "next_constraints" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "These values will be updated inside an iterative process, where previous and next constraints will be evaluated under a maximum of `tolerance`: " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "tolerance = 1e-3" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "np.abs(current_constraints, next_constraints).sum()" + "def children_cat(r):\n", + " if r.R18 == 1:\n", + " return \"yes\"\n", + " return \"no\"" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 38, "metadata": {}, "outputs": [], "source": [ - "if np.abs(current_constraints, next_constraints).sum()>tolerance:\n", - " print('Recalculate constraints table')" + "h_pums, jd_households = cat.joint_distribution(h_pums,\n", + " cat.category_combinations(h_acs_cat.columns),\n", + " {\"hh_cars\": cars_cat,\n", + " \"hh_children\": children_cat,\n", + " })" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "This way, the iteration will continue until reaching a group of new target values under the tolerance defined before. The man result of this process will be..." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# ... our marginals table with total values for the block group\n", - "hh_marginals_tract_400_block_gp_1" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# updated with new totals.\n", - "h_constraint" + "- **1. Categories dataframe**\n", + "\n", + "This cointains the amount of cases (or frequencies) for each category combination within the PUMA geography. It is important to remark that this totals corresponds to all the tracts we passed to the `tract to puma` function. Given that PUMS returns individual answers for a bunch of variables, we can combine them based on acs subject table columns and get the totals of each combination for a group tracts. This will return a total value for a group of tracts (or PUMA). PUMAs are unique whitin a state." ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 39, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
cat_idfrequency
hh_carshh_children
noneno0843
yes1919
oneno2573
yes3431
two or moreno4491
yes5368
\n", + "
" + ], + "text/plain": [ + " cat_id frequency\n", + "hh_cars hh_children \n", + "none no 0 843\n", + " yes 1 919\n", + "one no 2 573\n", + " yes 3 431\n", + "two or more no 4 491\n", + " yes 5 368" + ] + }, + "execution_count": 39, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "# that will be used to update joint distributions frequencies\n", "jd_households" ] }, @@ -1421,547 +2741,3423 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Consuming the Census API we built a dataset with, for example, 91 aggregated cases for households with no car. Building the constraints table, we used PUMA geographies to determine the proportion that these 91 cases represents in a more dissaggregated level. With this estimation we determine that instead of 91, the block group 1 of the census tract 00400 from the Yukon-Koyukuk county in the Alaska state has 46.5 households with no car. " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.2. The iterative proportional updating (IPU) procedure " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "![ipu](img/ipf_ipu.png)" + "- **2. Sample dataframe**\n", + "\n", + "This is the microdata puma df we downloaded for tracts 100 to 400, with a new `cat_id` combination column:" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 40, "metadata": {}, - "outputs": [], - "source": [ - "from synthpop.ipu.ipu import household_weights" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
serialnoRTpuma00puma10NPTYPEBLDTENVEHHINCPMVR18R65hh_carshh_childrencat_id
02012000000643H-9400212.03.00.033360.01.00.00.0noneno0
22012000001889H-9400412.02.00.089420.07.00.02.0noneno0
32012000003083H-9400112.02.00.020800.07.00.00.0noneno0
152012000017291H-9400412.02.00.054800.05.00.00.0noneno0
312012000041419H-9400212.02.00.033300.07.00.01.0noneno0
...................................................
57622011001370081H400-9112.02.06.0300300.05.00.00.0two or moreno4
57712011001380825H400-9212.04.02.0173600.01.00.00.0two or moreno4
58352011001457691H400-9211.03.02.097400.03.00.00.0two or moreno4
58432011001464975H400-9412.01.02.08650.05.00.00.0two or moreno4
58622011001495660H400-9312.02.02.029500.07.00.02.0two or moreno4
\n", + "

3625 rows × 16 columns

\n", + "
" + ], + "text/plain": [ + " serialno RT puma00 puma10 NP TYPE BLD TEN VEH HINCP MV \\\n", + "0 2012000000643 H -9 400 2 1 2.0 3.0 0.0 33360.0 1.0 \n", + "2 2012000001889 H -9 400 4 1 2.0 2.0 0.0 89420.0 7.0 \n", + "3 2012000003083 H -9 400 1 1 2.0 2.0 0.0 20800.0 7.0 \n", + "15 2012000017291 H -9 400 4 1 2.0 2.0 0.0 54800.0 5.0 \n", + "31 2012000041419 H -9 400 2 1 2.0 2.0 0.0 33300.0 7.0 \n", + "... ... .. ... ... .. ... ... ... ... ... ... \n", + "5762 2011001370081 H 400 -9 1 1 2.0 2.0 6.0 300300.0 5.0 \n", + "5771 2011001380825 H 400 -9 2 1 2.0 4.0 2.0 173600.0 1.0 \n", + "5835 2011001457691 H 400 -9 2 1 1.0 3.0 2.0 97400.0 3.0 \n", + "5843 2011001464975 H 400 -9 4 1 2.0 1.0 2.0 8650.0 5.0 \n", + "5862 2011001495660 H 400 -9 3 1 2.0 2.0 2.0 29500.0 7.0 \n", + "\n", + " R18 R65 hh_cars hh_children cat_id \n", + "0 0.0 0.0 none no 0 \n", + "2 0.0 2.0 none no 0 \n", + "3 0.0 0.0 none no 0 \n", + "15 0.0 0.0 none no 0 \n", + "31 0.0 1.0 none no 0 \n", + "... ... ... ... ... ... \n", + "5762 0.0 0.0 two or more no 4 \n", + "5771 0.0 0.0 two or more no 4 \n", + "5835 0.0 0.0 two or more no 4 \n", + "5843 0.0 0.0 two or more no 4 \n", + "5862 0.0 2.0 two or more no 4 \n", + "\n", + "[3625 rows x 16 columns]" + ] + }, + "execution_count": 40, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "h_constraint.index = jd_households.cat_id" + "h_pums" ] }, { - "cell_type": "code", - "execution_count": null, + "cell_type": "markdown", "metadata": {}, - "outputs": [], "source": [ - "h_constraint" + "**Until this point, we...**:\n", + "1. Queried the `acs5` subject table to get persons and households variables at block group and tracts levels\n", + "2. Downloaded sample files (PUMS) containing the same variables with different standard names.\n", + "3. Matched the tracts of the `county`, `state` pair with a puma id.\n", + "4. Built combination of variables at puma level - or all the tracts that are cointained inside a puma id (e.g. households with no children and no cars)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "Besides the `categories dataframe` - our joint distributions table- we mentioned in `2.3`, there is a `sample dataframe` which is the public user microdata sample - our pums." + "### 2.4. Marginals, the block group level" ] }, { - "cell_type": "code", - "execution_count": null, + "cell_type": "markdown", "metadata": {}, - "outputs": [], "source": [ - "households_sample_df = h_pums.copy()" + "Marginals are called from the `starter` object inside the `synthesize_all` function and returns..." ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 41, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "state 02\n", + "county 290\n", + "tract 000100\n", + "block group 1\n", + "dtype: object" + ] + }, + "execution_count": 41, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "households_sample_df.head()" + "#...for a group of available geographies inside a county/state pair\n", + "list(starter.get_available_geography_ids())[0]" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 42, "metadata": {}, "outputs": [], "source": [ - "households_sample_df.index.name = \"hh_id\"" + "indexes = starter.get_available_geography_ids()" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 43, "metadata": {}, "outputs": [], "source": [ - "households_sample_df = households_sample_df.reset_index().set_index(\"serialno\")" + "for geog_id in indexes:\n", + " h_marg = starter.get_household_marginal_for_geography(geog_id)" ] }, { - "cell_type": "code", - "execution_count": null, + "cell_type": "markdown", "metadata": {}, - "outputs": [], "source": [ - "h_freq_table = cat._frequency_table(households_sample_df, jd_households.cat_id)" + "***...the total value of a given variable for the block group geography levels:***" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 44, "metadata": {}, - "outputs": [], - "source": [ - "h_freq_table = h_freq_table.sort_index(axis=1)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "cat_name cat_value \n", + "hh_age_of_head gt35-lt65 108\n", + " gt65 46\n", + " lt35 38\n", + "hh_cars none 98\n", + " one 50\n", + " two or more 43\n", + "hh_children no 123\n", + " yes 69\n", + "hh_income gt100-lt150 16\n", + " gt150 6\n", + " gt30-lt60 32\n", + " gt60-lt100 81\n", + " lt30 57\n", + "hh_race_of_head asian 0\n", + " black 2\n", + " other 108\n", + " white 82\n", + "hh_size four or more 36\n", + " one 61\n", + " three 44\n", + " two 51\n", + "hh_workers none 69\n", + " one 77\n", + " two or more 45\n", + "hispanic_head no 188\n", + " yes 4\n", + "seniors no 144\n", + " yes 48\n", + "sf_detached no 7\n", + " yes 185\n", + "tenure_mover own not recent 97\n", + " own recent 8\n", + " rent not recent 69\n", + " rent recent 18\n", + "Name: (02, 290, 000400, 2), dtype: int64" + ] + }, + "execution_count": 44, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "h_freq_table.head()" + "# This is the marginal table we stored for the last census tract (400)\n", + "h_marg" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "Togheter, frequency tables and constraints will be used for weights matrix and fit quality:" + "For example, in our acs5 categorized table, in the block group 1 of the 000400 tract (we only stored the last geography since we ran a for loop) there are 82 households with childs and 46 with one car." ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 45, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
cat_namehh_carshh_children
cat_valuenoneonetwo or morenoyes
statecountytractblock group
022900001001119402612958
2214714825482
000200151738215157
28312013524398
00030011275847126108
2103473811476
3102463812167
00040019146399882
298504312369
\n", + "
" + ], + "text/plain": [ + "cat_name hh_cars hh_children \n", + "cat_value none one two or more no yes\n", + "state county tract block group \n", + "02 290 000100 1 119 40 26 129 58\n", + " 2 214 71 48 254 82\n", + " 000200 1 51 73 82 151 57\n", + " 2 83 120 135 243 98\n", + " 000300 1 127 58 47 126 108\n", + " 2 103 47 38 114 76\n", + " 3 102 46 38 121 67\n", + " 000400 1 91 46 39 98 82\n", + " 2 98 50 43 123 69" + ] + }, + "execution_count": 45, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "best_weights, fit_quality, iterations = household_weights(h_freq_table,\n", - " None,\n", - " h_constraint,\n", - " None)" + "# can check these totals in our acs subject table...\n", + "h_acs_cat" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 46, "metadata": {}, "outputs": [], "source": [ - "from synthpop.ipu.ipu import _FrequencyAndConstraints" + "# store the marginal values from the block group 1 of the 000400 census tract\n", + "hh_marginals_tract_400_block_gp_1 = h_acs_cat.loc[tuple(list(starter.get_available_geography_ids())[7])]" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 47, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "cat_name cat_value \n", + "hh_cars none 91\n", + " one 46\n", + " two or more 39\n", + "hh_children no 98\n", + " yes 82\n", + "Name: (02, 290, 000400, 1), dtype: int64" + ] + }, + "execution_count": 47, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "freq_wrap = _FrequencyAndConstraints(h_freq_table, h_constraint)" + "hh_marginals_tract_400_block_gp_1" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "This wrapper returns every `cat_id` column with non zero values:\n", - "\n", - "* `0` represents households with no car and no children \n", - "* `1` represents households with no car and children \n", - "* `2` represents households with one car and no children\n", - "* `3` represents households with one car and children\n", - "* `4` represents households with two or more cars and no children\n", - "* `5` represents households with two or more cars and children\n", - "\n", - "The wrapper returns each variables combination (from 0 to 5) inside a tuple with:\n", - "\n", - "1) `cat_id` value\n", - "\n", - "2) a `weights matrix`\n", - "\n", - "3) the new target value (the `constraint` or maximum value that the combination can reach within the block group) we built in the `ipf`.\n", - "\n", - "4) the index of non zero column values " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# here the information for all the combinations\n", - "freq_wrap.iter_columns()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# and here, we can see for category \"0\" that non zero values are...\n", - "freq_wrap.get_column(0)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "#... in the index 0, 1, 2, 7, (...)\n", - "h_freq_table[0][0:8]" + "## 3. Sinthesize all: using `Starter` outputs " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "With this wrapper, we build the fit quality od each `cat_id`" + "### 3.1 The iterative proportional fitting (IPF) procedure " ] }, { - "cell_type": "code", - "execution_count": null, + "cell_type": "markdown", "metadata": {}, - "outputs": [], "source": [ - "from synthpop.ipu.ipu import _average_fit_quality\n", - "from synthpop.ipu.ipu import _fit_quality" + "![constraints](img/constraints.png)" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 48, "metadata": {}, "outputs": [], "source": [ - "# weights matrix\n", - "weights = np.ones(len(h_freq_table), dtype='float')\n", - "\n", - "# column (this is the non-zero elements of the \"0\" cat_id column of the frequency table)\n", - "cat_id_0_column = [e for e in freq_wrap.get_column(0)][1]\n", - "\n", - "# nz (this is the idx of the frequency table where non zero values are stored)\n", - "cat_id_0_nz = [e for e in freq_wrap.get_column(0)][3]" + "from synthpop.ipf.ipf import calculate_constraints" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 49, "metadata": {}, "outputs": [], "source": [ - "# the non zero values should have the same length when filtering the weights matrix\n", - "len(cat_id_0_column) == len(weights[cat_id_0_nz])" + "h_constraint, _ = calculate_constraints(hh_marginals_tract_400_block_gp_1, jd_households.frequency)" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 50, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "hh_cars hh_children\n", + "none no 46.529753\n", + " yes 46.538428\n", + "one no 27.835805\n", + " yes 19.209650\n", + "two or more no 23.634442\n", + " yes 16.251921\n", + "dtype: float64" + ] + }, + "execution_count": 50, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "# the new target value for the block group\n", - "constraint = [e for e in freq_wrap.get_column(0)][2]" + "# this is our contraints table\n", + "h_constraint" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 51, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "4" + ] + }, + "execution_count": 51, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "# this is the \"fit quality\" value for cat_id \"0\"\n", - "_fit_quality(cat_id_0_column, weights[cat_id_0_nz], constraint)" + "# this is the number of iterations performed to achieve the constraint values\n", + "_" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "This value is the result of multiplying the non-zero values by the weights matrix, which returns the total frequency of the category within the PUMA: " + "In the block group 1 of the census tract 400 we used to have 91 households with no cars, 46 with one car and 39 with two or more:" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 52, "metadata": {}, "outputs": [], "source": [ - "(cat_id_0_column * weights[cat_id_0_nz]).sum()" + "bg_targets = hh_marginals_tract_400_block_gp_1[:3]" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 53, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "cat_name cat_value \n", + "hh_cars none 91\n", + " one 46\n", + " two or more 39\n", + "Name: (02, 290, 000400, 1), dtype: int64" + ] + }, + "execution_count": 53, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "# Here the total households with no car and no children(843)\n", - "jd_households" + "bg_targets" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "The sum of non zero values is weighted and then reduced by substracting the constraints..." + "At the same time, our `joint_distributions` table gave us the total of that variable for the entire PUMA (in this case, `843 households with no children + 919 households with one children = 1762 households with no cars`:" ] }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "(cat_id_0_column * weights[cat_id_0_nz]).sum() - constraint" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "... and finally is expressed in terms of the constraint for that category - the 𝛿 parameter described in the IPU paper -. The absolute value of the relative difference between the weighted sum and the corresponding constraint may be used as a goodness of fit measure and is defined as: " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "((cat_id_0_column * weights[cat_id_0_nz]).sum() - constraint) / constraint" - ] - }, - { - "cell_type": "markdown", + "execution_count": 54, "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
cat_idfrequency
hh_carshh_children
noneno0843
yes1919
\n", + "
" + ], + "text/plain": [ + " cat_id frequency\n", + "hh_cars hh_children \n", + "none no 0 843\n", + " yes 1 919" + ] + }, + "execution_count": 54, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "This is basically showing the proportion of the `cat_id` within the entire population of the PUMA. In the example of this first iteration, we have that for each household that `cat_id` == `0`, there are 17 households that could be out of that category (`cat_id` != `0`). " + "jd_households[:2]" ] }, { - "cell_type": "markdown", + "cell_type": "code", + "execution_count": 55, "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "1762" + ] + }, + "execution_count": 55, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "![constraints](img/ipu.png)" + "jd_households['frequency'][:2].sum()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "This process will be repeated for all household types (or `cat_id`) and build a unique average value (which is the sum of each `_fit_quality` result divided by the number of `cat_id` columns):" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "fit_qual_0_to_5 = _average_fit_quality(freq_wrap, weights)" + "With this information, we will build new target values for each category total within the block group by multiplying the target and the proportion that this target represents in the entire PUMA - remember here, that our joint distribution table gets this total by combining different variables. In our case number of cars and children -\n", + "\n", + "`new_target = current_target * (proportion of the current target)`" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 56, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Block group target value: 91\n", + "Total value of the combined category is: 1762\n", + "Proportion of each category in the combined variables total: 0.051645856980703744\n", + "New Block group target value: 4.69977298524404\n", + "*********************************************************************************\n", + "Block group target value: 46\n", + "Total value of the combined category is: 1004\n", + "Proportion of each category in the combined variables total: 0.045816733067729085\n", + "New Block group target value: 2.1075697211155378\n", + "*********************************************************************************\n", + "Block group target value: 39\n", + "Total value of the combined category is: 859\n", + "Proportion of each category in the combined variables total: 0.04540162980209546\n", + "New Block group target value: 1.7706635622817228\n", + "*********************************************************************************\n" + ] + } + ], "source": [ - "fit_qual_0_to_5" + "sub_category_idx_0 = 0\n", + "sub_category_idx_1 = 2\n", + "\n", + "for target in range(len(bg_targets)):\n", + " total_cat = jd_households.frequency[sub_category_idx_0:sub_category_idx_1].sum()\n", + " sub_category_idx_0 += 2\n", + " sub_category_idx_1 += 2\n", + " print('Block group target value: %s'%str(bg_targets[target]))\n", + " print('Total value of the combined category is: %s'%str(total_cat))\n", + " print('Proportion of each category in the combined variables total: %s'%str(bg_targets[target] / total_cat))\n", + " print('New Block group target value: %s'%str(bg_targets[target]*(bg_targets[target] / total_cat)))\n", + " print('*********************************************************************************')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "As it is explained on [A METHODOLOGY TO MATCH DISTRIBUTIONS OF BOTH HOUSEHOLD AND\n", - "PERSON ATTRIBUTES IN THE GENERATION OF SYNTHETIC POPULATIONS ](http://www.scag.ca.gov/Documents/PopulationSynthesizerPaper_TRB.pdf), the IPU algorithm starts by assuming equal weights for all households in the sample. The algorithm then proceeds by adjusting weights for each household/person constraint in an iterative process until the constraints are matched as closely as possible for both household and person attributes. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "fit_change = np.inf\n", - "convergence= 1e-4" + "These new values that were built based on the proportion that each block group represents in the PUMA (for every category value) will be used to update our joint distributions table: " ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 57, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "array([[ 0, 843],\n", + " [ 1, 919],\n", + " [ 2, 573],\n", + " [ 3, 431],\n", + " [ 4, 491],\n", + " [ 5, 368]])" + ] + }, + "execution_count": 57, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "if fit_change > convergence:\n", - " print(\"Updating weights matrix until reaching a fit quality value under the convergence!\")" + "jd_households.values" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "The weights for the each household level constraint are adjusted by dividing the number of households in that category (i.e., the constraint value) by the weighted sum of the first household type column: \n", - "\n", - "The `_update_weights` creates the following adjustment `adj = constraint / float((column * weights).sum())` and use it to update weights (`weights * adj`). The weights for all households of each household type will be multiplied by this ratio to satisfy the constraint. " + "...the totals we had for each `category combination`: 0; 1; 2; 3; 4 & 5 will be replaced using that proportion. This way we will define a new maximum value for every category within the block group." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "In this sense, the `households_weights` function will finally return a:" + "Imagine we have a constraints table with categories from 0 to 2 (has no car and no children, has no car but children and has one car and no children) as we shown in the example above. We will need to:" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 58, "metadata": {}, "outputs": [], "source": [ - "# 1. An array of corrected weights that best matches each household type \n", - "best_weights" + "current_constraints = jd_households[:3].values.copy()" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 59, "metadata": {}, "outputs": [], "source": [ - "# 2. And a fit quality based on the proportion of each hh type that reduces the fit changes under the convergence \n", - "fit_quality" + "# 1. define new targets based on proportions\n", + "new_targets = [4.69977298524404, 2.1075697211155378, 1.7706635622817228]\n", + "\n", + "next_constraints = current_constraints.astype(float)" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 60, "metadata": {}, "outputs": [], "source": [ - "# 3. Built in ...\n", - "iterations" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# 4. Drawing synthetic population " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "![draw](img/draw.png)" + "# 2. update the constraints table\n", + "fre = -1\n", + "for t in new_targets:\n", + " fre +=1 \n", + " next_constraints[fre][1] = t" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 61, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "array([[0. , 4.69977299],\n", + " [1. , 2.10756972],\n", + " [2. , 1.77066356]])" + ] + }, + "execution_count": 61, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "from synthpop import draw" + "next_constraints" ] }, { - "cell_type": "code", - "execution_count": null, + "cell_type": "markdown", "metadata": {}, - "outputs": [], "source": [ - "num_households = int(hh_marginals_tract_400_block_gp_1.groupby(level=0).sum().mean())" + "These values will be updated inside an iterative process, where previous and next constraints will be evaluated under a maximum of `tolerance`: " ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 62, "metadata": {}, "outputs": [], "source": [ - "num_households" + "tolerance = 1e-3" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 63, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "2338.0" + ] + }, + "execution_count": 63, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "fac = _FrequencyAndConstraints(h_freq_table, h_constraint)" + "np.abs(current_constraints, next_constraints).sum()" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 64, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Recalculate constraints table\n" + ] + } + ], "source": [ - "indexes = draw._draw_indexes(num_households, fac, best_weights)" + "if np.abs(current_constraints, next_constraints).sum()>tolerance:\n", + " print('Recalculate constraints table')" ] }, { - "cell_type": "code", - "execution_count": null, + "cell_type": "markdown", "metadata": {}, - "outputs": [], "source": [ - "indexes" + "This way, the iteration will continue until reaching a group of new target values under the tolerance defined before. The man result of this process will be..." ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 65, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "cat_name cat_value \n", + "hh_cars none 91\n", + " one 46\n", + " two or more 39\n", + "hh_children no 98\n", + " yes 82\n", + "Name: (02, 290, 000400, 1), dtype: int64" + ] + }, + "execution_count": 65, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "synth_hh = h_pums.loc[indexes].reset_index(drop=True)" + "# ... our marginals table with total values for the block group\n", + "hh_marginals_tract_400_block_gp_1" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 66, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "hh_cars hh_children\n", + "none no 46.529753\n", + " yes 46.538428\n", + "one no 27.835805\n", + " yes 19.209650\n", + "two or more no 23.634442\n", + " yes 16.251921\n", + "dtype: float64" + ] + }, + "execution_count": 66, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "synth_hh" + "# updated with new totals.\n", + "h_constraint" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 67, "metadata": {}, - "outputs": [], - "source": [ - "mrg_tbl = pd.DataFrame(\n", - " {'serialno': synth_hh.serialno.values,\n", - " 'hh_id': synth_hh.index.values})" - ] - }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
cat_idfrequency
hh_carshh_children
noneno0843
yes1919
oneno2573
yes3431
two or moreno4491
yes5368
\n", + "
" + ], + "text/plain": [ + " cat_id frequency\n", + "hh_cars hh_children \n", + "none no 0 843\n", + " yes 1 919\n", + "one no 2 573\n", + " yes 3 431\n", + "two or more no 4 491\n", + " yes 5 368" + ] + }, + "execution_count": 67, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# that will be used to update joint distributions frequencies\n", + "jd_households" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Consuming the Census API we built a dataset with, for example, 91 aggregated cases for households with no car. Building the constraints table, we used PUMA geographies to determine the proportion that these 91 cases represents in a more dissaggregated level. With this estimation we determine that instead of 91, the block group 1 of the census tract 00400 from the Yukon-Koyukuk county in the Alaska state has 46.5 households with no car. " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 3.2. The iterative proportional updating (IPU) procedure " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "![ipu](img/ipf_ipu.png)" + ] + }, + { + "cell_type": "code", + "execution_count": 68, + "metadata": {}, + "outputs": [], + "source": [ + "from synthpop.ipu.ipu import household_weights" + ] + }, + { + "cell_type": "code", + "execution_count": 69, + "metadata": {}, + "outputs": [], + "source": [ + "h_constraint.index = jd_households.cat_id" + ] + }, + { + "cell_type": "code", + "execution_count": 70, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "cat_id\n", + "0 46.529753\n", + "1 46.538428\n", + "2 27.835805\n", + "3 19.209650\n", + "4 23.634442\n", + "5 16.251921\n", + "dtype: float64" + ] + }, + "execution_count": 70, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "h_constraint" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Besides the `categories dataframe` - our joint distributions table- we mentioned in `2.3`, there is a `sample dataframe` which is the public user microdata sample - our pums." + ] + }, + { + "cell_type": "code", + "execution_count": 71, + "metadata": {}, + "outputs": [], + "source": [ + "households_sample_df = h_pums.copy()" + ] + }, + { + "cell_type": "code", + "execution_count": 72, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
serialnoRTpuma00puma10NPTYPEBLDTENVEHHINCPMVR18R65hh_carshh_childrencat_id
02012000000643H-9400212.03.00.033360.01.00.00.0noneno0
22012000001889H-9400412.02.00.089420.07.00.02.0noneno0
32012000003083H-9400112.02.00.020800.07.00.00.0noneno0
152012000017291H-9400412.02.00.054800.05.00.00.0noneno0
312012000041419H-9400212.02.00.033300.07.00.01.0noneno0
\n", + "
" + ], + "text/plain": [ + " serialno RT puma00 puma10 NP TYPE BLD TEN VEH HINCP MV \\\n", + "0 2012000000643 H -9 400 2 1 2.0 3.0 0.0 33360.0 1.0 \n", + "2 2012000001889 H -9 400 4 1 2.0 2.0 0.0 89420.0 7.0 \n", + "3 2012000003083 H -9 400 1 1 2.0 2.0 0.0 20800.0 7.0 \n", + "15 2012000017291 H -9 400 4 1 2.0 2.0 0.0 54800.0 5.0 \n", + "31 2012000041419 H -9 400 2 1 2.0 2.0 0.0 33300.0 7.0 \n", + "\n", + " R18 R65 hh_cars hh_children cat_id \n", + "0 0.0 0.0 none no 0 \n", + "2 0.0 2.0 none no 0 \n", + "3 0.0 0.0 none no 0 \n", + "15 0.0 0.0 none no 0 \n", + "31 0.0 1.0 none no 0 " + ] + }, + "execution_count": 72, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "households_sample_df.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 73, + "metadata": {}, + "outputs": [], + "source": [ + "households_sample_df.index.name = \"hh_id\"" + ] + }, + { + "cell_type": "code", + "execution_count": 74, + "metadata": {}, + "outputs": [], + "source": [ + "households_sample_df = households_sample_df.reset_index().set_index(\"serialno\")" + ] + }, + { + "cell_type": "code", + "execution_count": 75, + "metadata": {}, + "outputs": [], + "source": [ + "h_freq_table = cat._frequency_table(households_sample_df, jd_households.cat_id)" + ] + }, + { + "cell_type": "code", + "execution_count": 76, + "metadata": {}, + "outputs": [], + "source": [ + "h_freq_table = h_freq_table.sort_index(axis=1)" + ] + }, + { + "cell_type": "code", + "execution_count": 77, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
cat_id012345
hh_id
01.00.00.00.00.00.0
21.00.00.00.00.00.0
31.00.00.00.00.00.0
40.01.00.00.00.00.0
50.00.00.01.00.00.0
\n", + "
" + ], + "text/plain": [ + "cat_id 0 1 2 3 4 5\n", + "hh_id \n", + "0 1.0 0.0 0.0 0.0 0.0 0.0\n", + "2 1.0 0.0 0.0 0.0 0.0 0.0\n", + "3 1.0 0.0 0.0 0.0 0.0 0.0\n", + "4 0.0 1.0 0.0 0.0 0.0 0.0\n", + "5 0.0 0.0 0.0 1.0 0.0 0.0" + ] + }, + "execution_count": 77, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "h_freq_table.head()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Togheter, frequency tables and constraints will be used for weights matrix and fit quality:" + ] + }, + { + "cell_type": "code", + "execution_count": 78, + "metadata": {}, + "outputs": [], + "source": [ + "best_weights, fit_quality, iterations = household_weights(h_freq_table,\n", + " None,\n", + " h_constraint,\n", + " None)" + ] + }, + { + "cell_type": "code", + "execution_count": 79, + "metadata": {}, + "outputs": [], + "source": [ + "from synthpop.ipu.ipu import _FrequencyAndConstraints" + ] + }, + { + "cell_type": "code", + "execution_count": 80, + "metadata": {}, + "outputs": [], + "source": [ + "freq_wrap = _FrequencyAndConstraints(h_freq_table, h_constraint)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This wrapper returns every `cat_id` column with non zero values:\n", + "\n", + "* `0` represents households with no car and no children \n", + "* `1` represents households with no car and children \n", + "* `2` represents households with one car and no children\n", + "* `3` represents households with one car and children\n", + "* `4` represents households with two or more cars and no children\n", + "* `5` represents households with two or more cars and children\n", + "\n", + "The wrapper returns each variables combination (from 0 to 5) inside a tuple with:\n", + "\n", + "1) `cat_id` value\n", + "\n", + "2) a `weights matrix`\n", + "\n", + "3) the new target value (the `constraint` or maximum value that the combination can reach within the block group) we built in the `ipf`.\n", + "\n", + "4) the index of non zero column values " + ] + }, + { + "cell_type": "code", + "execution_count": 81, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[(0,\n", + " array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.]),\n", + " 46.529753144154704,\n", + " array([ 0, 1, 2, 7, 16, 18, 20, 27, 32, 34, 38,\n", + " 41, 47, 58, 60, 74, 84, 86, 87, 88, 90, 95,\n", + " 97, 99, 106, 107, 108, 115, 116, 118, 121, 122, 130,\n", + " 131, 135, 138, 140, 159, 163, 165, 169, 175, 182, 190,\n", + " 192, 205, 207, 211, 212, 214, 215, 221, 223, 226, 227,\n", + " 228, 229, 232, 235, 240, 242, 256, 261, 268, 270, 279,\n", + " 280, 281, 282, 283, 285, 287, 291, 295, 297, 298, 299,\n", + " 300, 308, 309, 310, 311, 315, 320, 324, 331, 332, 336,\n", + " 338, 345, 356, 361, 363, 366, 367, 368, 372, 380, 383,\n", + " 388, 393, 400, 403, 406, 408, 418, 419, 430, 432, 433,\n", + " 434, 449, 450, 465, 466, 471, 472, 473, 483, 486, 499,\n", + " 504, 513, 514, 519, 537, 538, 540, 545, 546, 548, 552,\n", + " 553, 559, 565, 573, 579, 580, 583, 585, 589, 590, 597,\n", + " 598, 609, 613, 622, 624, 629, 632, 635, 636, 637, 638,\n", + " 641, 642, 646, 649, 650, 660, 661, 669, 672, 673, 684,\n", + " 687, 692, 697, 698, 706, 713, 716, 725, 727, 737, 738,\n", + " 739, 741, 747, 751, 754, 761, 762, 768, 797, 804, 805,\n", + " 809, 814, 815, 820, 822, 824, 825, 826, 837, 839, 840,\n", + " 842, 847, 855, 863, 866, 868, 872, 876, 887, 891, 901,\n", + " 905, 911, 916, 917, 923, 937, 939, 942, 945, 946, 952,\n", + " 960, 967, 969, 970, 973, 974, 975, 978, 984, 989, 990,\n", + " 993, 997, 999, 1000, 1005, 1006, 1009, 1011, 1015, 1021, 1022,\n", + " 1024, 1031, 1037, 1040, 1043, 1044, 1057, 1059, 1062, 1063, 1071,\n", + " 1072, 1073, 1079, 1083, 1090, 1093, 1094, 1096, 1097, 1101, 1106,\n", + " 1107, 1108, 1114, 1118, 1124, 1130, 1137, 1138, 1140, 1143, 1144,\n", + " 1161, 1171, 1175, 1178, 1180, 1186, 1187, 1188, 1192, 1196, 1197,\n", + " 1204, 1226, 1247, 1252, 1253, 1254, 1256, 1259, 1261, 1263, 1267,\n", + " 1271, 1279, 1285, 1292, 1295, 1302, 1305, 1308, 1317, 1319, 1321,\n", + " 1324, 1331, 1333, 1335, 1354, 1355, 1357, 1358, 1361, 1362, 1366,\n", + " 1367, 1373, 1382, 1395, 1396, 1397, 1406, 1407, 1408, 1409, 1415,\n", + " 1421, 1425, 1426, 1427, 1429, 1434, 1444, 1445, 1452, 1456, 1460,\n", + " 1461, 1466, 1474, 1480, 1481, 1482, 1490, 1491, 1493, 1501, 1509,\n", + " 1521, 1528, 1545, 1552, 1566, 1567, 1570, 1576, 1577, 1580, 1582,\n", + " 1594, 1603, 1605, 1618, 1619, 1627, 1628, 1643, 1645, 1650, 1653,\n", + " 1654, 1655, 1657, 1660, 1661, 1662, 1664, 1674, 1679, 1688, 1691,\n", + " 1692, 1701, 1704, 1705, 1709, 1710, 1711, 1712, 1713, 1715, 1729,\n", + " 1730, 1731, 1738, 1739, 1741, 1746, 1751, 1766, 1770, 1779, 1783,\n", + " 1785, 1787, 1800, 1802, 1811, 1816, 1820, 1821, 1824, 1829, 1833,\n", + " 1843, 1848, 1850, 1851, 1856, 1861, 1865, 1866, 1867, 1870, 1874,\n", + " 1875, 1878, 1883, 1887, 1890, 1891, 1893, 1897, 1903, 1904, 1905,\n", + " 1907, 1917, 1918, 1920, 1923, 1924, 1932, 1934, 1937, 1947, 1953,\n", + " 1957, 1958, 1962, 1965, 1971, 1972, 1975, 1976, 1979, 1980, 1998,\n", + " 2000, 2003, 2008, 2013, 2021, 2025, 2028, 2032, 2034, 2036, 2041,\n", + " 2048, 2049, 2056, 2061, 2064, 2068, 2070, 2076, 2080, 2086, 2090,\n", + " 2093, 2096, 2102, 2112, 2120, 2124, 2131, 2132, 2133, 2138, 2144,\n", + " 2146, 2159, 2165, 2167, 2173, 2174, 2183, 2184, 2189, 2198, 2200,\n", + " 2203, 2204, 2210, 2213, 2219, 2220, 2228, 2233, 2234, 2240, 2241,\n", + " 2251, 2252, 2255, 2260, 2264, 2265, 2267, 2273, 2280, 2283, 2284,\n", + " 2285, 2286, 2289, 2291, 2293, 2294, 2295, 2297, 2309, 2313, 2314,\n", + " 2317, 2321, 2331, 2335, 2344, 2350, 2352, 2364, 2369, 2370, 2371,\n", + " 2380, 2393, 2396, 2402, 2403, 2404, 2411, 2412, 2415, 2423, 2435,\n", + " 2445, 2447, 2450, 2453, 2466, 2469, 2476, 2481, 2491, 2495, 2507,\n", + " 2513, 2514, 2518, 2519, 2527, 2530, 2532, 2535, 2536, 2539, 2542,\n", + " 2545, 2546, 2547, 2559, 2562, 2565, 2577, 2579, 2584, 2588, 2593,\n", + " 2594, 2596, 2598, 2603, 2604, 2610, 2612, 2615, 2621, 2622, 2623,\n", + " 2631, 2638, 2642, 2646, 2647, 2654, 2659, 2660, 2661, 2662, 2667,\n", + " 2671, 2677, 2684, 2686, 2688, 2689, 2692, 2694, 2701, 2702, 2703,\n", + " 2705, 2706, 2712, 2714, 2715, 2717, 2719, 2724, 2728, 2729, 2735,\n", + " 2739, 2742, 2744, 2748, 2750, 2755, 2757, 2768, 2770, 2773, 2774,\n", + " 2776, 2777, 2778, 2779, 2780, 2785, 2790, 2791, 2792, 2802, 2803,\n", + " 2806, 2812, 2818, 2824, 2828, 2829, 2831, 2848, 2849, 2857, 2858,\n", + " 2861, 2864, 2872, 2874, 2877, 2882, 2884, 2885, 2890, 2898, 2900,\n", + " 2902, 2906, 2911, 2913, 2922, 2926, 2934, 2935, 2943, 2953, 2955,\n", + " 2964, 2967, 2969, 2972, 2973, 2981, 2983, 2984, 2985, 2988, 2990,\n", + " 2996, 2997, 3002, 3009, 3010, 3012, 3024, 3025, 3030, 3035, 3036,\n", + " 3043, 3045, 3047, 3052, 3053, 3055, 3062, 3069, 3072, 3077, 3079,\n", + " 3080, 3084, 3089, 3095, 3098, 3116, 3118, 3124, 3128, 3138, 3145,\n", + " 3148, 3166, 3168, 3173, 3174, 3178, 3185, 3193, 3205, 3208, 3214,\n", + " 3218, 3232, 3237, 3240, 3247, 3256, 3259, 3262, 3263, 3266, 3267,\n", + " 3270, 3273, 3287, 3294, 3296, 3301, 3302, 3311, 3316, 3320, 3336,\n", + " 3341, 3345, 3353, 3356, 3357, 3363, 3365, 3366, 3367, 3369, 3371,\n", + " 3376, 3377, 3380, 3390, 3391, 3393, 3397, 3399, 3401, 3404, 3406,\n", + " 3410, 3415, 3419, 3421, 3424, 3429, 3431, 3432, 3443, 3444, 3457,\n", + " 3458, 3459, 3462, 3466, 3468, 3470, 3471, 3472, 3473, 3478, 3488,\n", + " 3490, 3494, 3497, 3499, 3503, 3505, 3520, 3532, 3544, 3546, 3547,\n", + " 3548, 3550, 3551, 3556, 3557, 3562, 3567, 3570, 3576, 3578, 3581,\n", + " 3582, 3596, 3611, 3616, 3617, 3618, 3623])),\n", + " (1,\n", + " array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1.]),\n", + " 46.538428452649654,\n", + " array([ 3, 6, 8, 9, 21, 28, 29, 31, 33, 43, 48,\n", + " 52, 53, 55, 56, 57, 64, 69, 70, 73, 80, 83,\n", + " 93, 96, 101, 102, 103, 111, 114, 117, 120, 126, 127,\n", + " 128, 133, 134, 136, 137, 145, 148, 157, 160, 161, 164,\n", + " 170, 172, 173, 177, 183, 188, 189, 193, 198, 199, 201,\n", + " 202, 204, 206, 216, 230, 241, 247, 249, 255, 260, 265,\n", + " 267, 275, 276, 286, 289, 292, 296, 302, 304, 313, 318,\n", + " 323, 327, 334, 335, 340, 343, 351, 370, 373, 374, 381,\n", + " 386, 392, 398, 399, 404, 405, 407, 410, 412, 415, 420,\n", + " 424, 435, 437, 442, 443, 446, 451, 452, 454, 455, 460,\n", + " 462, 470, 474, 476, 479, 484, 485, 489, 490, 497, 502,\n", + " 503, 505, 508, 512, 516, 522, 530, 531, 532, 534, 539,\n", + " 542, 554, 563, 564, 581, 584, 586, 592, 595, 599, 600,\n", + " 604, 614, 619, 621, 630, 631, 633, 647, 648, 651, 653,\n", + " 654, 657, 659, 675, 676, 678, 685, 690, 695, 701, 702,\n", + " 704, 705, 707, 708, 709, 712, 714, 715, 720, 721, 728,\n", + " 731, 735, 736, 742, 743, 744, 746, 750, 756, 757, 758,\n", + " 759, 765, 773, 778, 779, 783, 786, 787, 791, 802, 806,\n", + " 808, 813, 817, 819, 821, 823, 829, 831, 833, 834, 838,\n", + " 846, 851, 853, 857, 859, 861, 867, 873, 878, 883, 888,\n", + " 890, 893, 894, 899, 907, 908, 910, 918, 922, 924, 925,\n", + " 927, 929, 930, 931, 932, 934, 941, 947, 950, 955, 965,\n", + " 968, 971, 976, 982, 995, 998, 1001, 1016, 1017, 1018, 1026,\n", + " 1030, 1032, 1035, 1036, 1046, 1060, 1066, 1067, 1070, 1075, 1077,\n", + " 1082, 1100, 1104, 1110, 1112, 1115, 1117, 1120, 1129, 1131, 1132,\n", + " 1133, 1135, 1139, 1147, 1148, 1151, 1152, 1157, 1160, 1165, 1169,\n", + " 1183, 1189, 1194, 1202, 1210, 1213, 1214, 1220, 1224, 1227, 1233,\n", + " 1238, 1243, 1244, 1249, 1258, 1275, 1277, 1280, 1282, 1283, 1284,\n", + " 1287, 1289, 1293, 1301, 1307, 1310, 1313, 1315, 1320, 1329, 1330,\n", + " 1337, 1338, 1340, 1344, 1346, 1352, 1356, 1364, 1365, 1372, 1379,\n", + " 1384, 1394, 1402, 1405, 1412, 1414, 1418, 1419, 1424, 1428, 1431,\n", + " 1436, 1440, 1446, 1453, 1454, 1464, 1468, 1469, 1471, 1473, 1475,\n", + " 1478, 1486, 1487, 1496, 1497, 1498, 1500, 1503, 1507, 1511, 1512,\n", + " 1513, 1518, 1520, 1524, 1531, 1532, 1535, 1539, 1540, 1542, 1543,\n", + " 1553, 1557, 1560, 1563, 1568, 1578, 1581, 1584, 1585, 1587, 1589,\n", + " 1590, 1591, 1595, 1599, 1601, 1604, 1606, 1610, 1614, 1615, 1616,\n", + " 1620, 1631, 1640, 1648, 1656, 1658, 1663, 1665, 1668, 1671, 1680,\n", + " 1685, 1687, 1690, 1702, 1706, 1707, 1725, 1726, 1728, 1733, 1734,\n", + " 1736, 1740, 1750, 1754, 1755, 1760, 1762, 1769, 1773, 1775, 1778,\n", + " 1780, 1781, 1782, 1784, 1788, 1789, 1791, 1794, 1797, 1798, 1806,\n", + " 1810, 1815, 1818, 1822, 1827, 1831, 1832, 1834, 1836, 1838, 1855,\n", + " 1857, 1858, 1859, 1860, 1862, 1863, 1864, 1869, 1876, 1880, 1886,\n", + " 1888, 1894, 1899, 1901, 1909, 1913, 1915, 1919, 1921, 1925, 1926,\n", + " 1929, 1936, 1938, 1940, 1941, 1943, 1952, 1955, 1956, 1960, 1963,\n", + " 1966, 1970, 1973, 1981, 1984, 1991, 1999, 2001, 2002, 2004, 2006,\n", + " 2009, 2012, 2015, 2016, 2017, 2022, 2027, 2031, 2035, 2038, 2039,\n", + " 2047, 2051, 2055, 2063, 2065, 2067, 2071, 2077, 2079, 2083, 2084,\n", + " 2088, 2092, 2104, 2114, 2115, 2117, 2118, 2126, 2134, 2139, 2140,\n", + " 2142, 2145, 2147, 2148, 2155, 2156, 2160, 2161, 2168, 2169, 2175,\n", + " 2177, 2178, 2186, 2188, 2190, 2191, 2199, 2201, 2221, 2224, 2226,\n", + " 2229, 2230, 2232, 2239, 2243, 2246, 2247, 2248, 2249, 2250, 2254,\n", + " 2259, 2266, 2269, 2270, 2274, 2275, 2282, 2292, 2300, 2301, 2302,\n", + " 2304, 2305, 2306, 2311, 2312, 2320, 2323, 2327, 2332, 2342, 2346,\n", + " 2354, 2357, 2358, 2360, 2362, 2363, 2366, 2367, 2368, 2373, 2374,\n", + " 2375, 2376, 2377, 2379, 2382, 2385, 2388, 2392, 2397, 2399, 2407,\n", + " 2409, 2417, 2418, 2419, 2420, 2421, 2424, 2430, 2432, 2439, 2441,\n", + " 2443, 2449, 2451, 2454, 2465, 2474, 2478, 2498, 2499, 2501, 2502,\n", + " 2503, 2506, 2521, 2528, 2529, 2533, 2537, 2543, 2551, 2553, 2554,\n", + " 2556, 2564, 2569, 2572, 2573, 2576, 2578, 2580, 2585, 2587, 2600,\n", + " 2602, 2607, 2608, 2609, 2619, 2620, 2624, 2625, 2626, 2628, 2639,\n", + " 2640, 2648, 2651, 2658, 2664, 2673, 2679, 2680, 2697, 2698, 2708,\n", + " 2710, 2713, 2718, 2723, 2730, 2731, 2732, 2733, 2736, 2738, 2740,\n", + " 2741, 2743, 2746, 2749, 2751, 2752, 2756, 2761, 2766, 2767, 2782,\n", + " 2786, 2788, 2795, 2798, 2799, 2804, 2807, 2809, 2813, 2816, 2817,\n", + " 2821, 2822, 2826, 2836, 2841, 2850, 2854, 2859, 2865, 2867, 2869,\n", + " 2871, 2873, 2879, 2889, 2892, 2895, 2896, 2903, 2907, 2908, 2914,\n", + " 2917, 2923, 2927, 2929, 2932, 2936, 2941, 2946, 2948, 2949, 2957,\n", + " 2959, 2962, 2965, 2970, 2975, 2976, 2978, 2979, 2989, 2995, 2998,\n", + " 3001, 3003, 3005, 3006, 3008, 3014, 3017, 3018, 3021, 3023, 3028,\n", + " 3029, 3031, 3032, 3033, 3034, 3037, 3042, 3046, 3048, 3051, 3057,\n", + " 3063, 3066, 3074, 3081, 3083, 3085, 3103, 3106, 3113, 3114, 3121,\n", + " 3122, 3125, 3129, 3132, 3134, 3137, 3139, 3146, 3147, 3153, 3158,\n", + " 3160, 3169, 3171, 3172, 3177, 3179, 3188, 3189, 3190, 3192, 3199,\n", + " 3201, 3209, 3220, 3226, 3233, 3238, 3239, 3241, 3242, 3245, 3246,\n", + " 3249, 3250, 3251, 3252, 3253, 3254, 3260, 3261, 3264, 3265, 3268,\n", + " 3275, 3282, 3288, 3290, 3292, 3298, 3303, 3312, 3315, 3319, 3326,\n", + " 3328, 3330, 3339, 3347, 3351, 3360, 3361, 3373, 3375, 3379, 3381,\n", + " 3382, 3386, 3392, 3396, 3398, 3412, 3413, 3418, 3423, 3425, 3426,\n", + " 3430, 3433, 3434, 3436, 3442, 3447, 3452, 3456, 3461, 3465, 3474,\n", + " 3477, 3480, 3481, 3482, 3483, 3489, 3496, 3501, 3502, 3504, 3506,\n", + " 3510, 3514, 3517, 3518, 3519, 3524, 3527, 3530, 3533, 3534, 3536,\n", + " 3537, 3538, 3540, 3541, 3545, 3549, 3552, 3553, 3559, 3563, 3565,\n", + " 3566, 3572, 3575, 3577, 3579, 3580, 3583, 3586, 3587, 3597, 3598,\n", + " 3599, 3600, 3602, 3605, 3609, 3621])),\n", + " (2,\n", + " array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.]),\n", + " 27.835804541797003,\n", + " array([ 10, 11, 19, 22, 25, 26, 42, 44, 46, 71, 72,\n", + " 77, 85, 89, 94, 109, 110, 113, 123, 124, 144, 146,\n", + " 149, 151, 171, 174, 179, 184, 187, 194, 196, 197, 213,\n", + " 218, 224, 234, 243, 246, 248, 252, 253, 266, 271, 278,\n", + " 303, 307, 317, 321, 325, 333, 339, 341, 342, 357, 359,\n", + " 369, 376, 382, 395, 397, 409, 414, 416, 417, 421, 423,\n", + " 426, 436, 438, 445, 456, 457, 458, 467, 469, 480, 487,\n", + " 507, 510, 524, 527, 529, 535, 536, 547, 550, 551, 560,\n", + " 562, 566, 568, 569, 570, 571, 572, 575, 576, 582, 591,\n", + " 596, 602, 603, 605, 610, 617, 626, 644, 652, 658, 665,\n", + " 668, 670, 677, 680, 686, 689, 693, 700, 717, 726, 730,\n", + " 732, 740, 749, 753, 763, 766, 767, 772, 774, 776, 780,\n", + " 781, 785, 789, 792, 795, 810, 844, 848, 854, 856, 865,\n", + " 871, 874, 877, 881, 895, 896, 902, 903, 904, 906, 912,\n", + " 914, 915, 928, 935, 948, 957, 959, 963, 981, 986, 994,\n", + " 1014, 1020, 1025, 1045, 1055, 1065, 1099, 1123, 1134, 1136, 1141,\n", + " 1142, 1154, 1158, 1159, 1168, 1172, 1173, 1174, 1177, 1184, 1185,\n", + " 1191, 1193, 1199, 1200, 1201, 1206, 1222, 1223, 1229, 1230, 1234,\n", + " 1242, 1246, 1255, 1260, 1272, 1273, 1278, 1288, 1290, 1291, 1296,\n", + " 1316, 1325, 1326, 1334, 1336, 1343, 1345, 1348, 1350, 1353, 1359,\n", + " 1368, 1369, 1374, 1375, 1381, 1385, 1391, 1393, 1410, 1411, 1432,\n", + " 1451, 1462, 1483, 1516, 1517, 1519, 1525, 1527, 1529, 1530, 1541,\n", + " 1546, 1548, 1556, 1559, 1565, 1573, 1583, 1597, 1600, 1609, 1617,\n", + " 1621, 1624, 1625, 1629, 1633, 1634, 1642, 1646, 1647, 1649, 1651,\n", + " 1659, 1667, 1672, 1677, 1689, 1699, 1716, 1717, 1718, 1720, 1742,\n", + " 1748, 1757, 1764, 1767, 1772, 1777, 1786, 1792, 1804, 1809, 1812,\n", + " 1813, 1825, 1826, 1828, 1842, 1854, 1873, 1882, 1884, 1900, 1902,\n", + " 1906, 1911, 1935, 1942, 1948, 1951, 1954, 1964, 1968, 1988, 1993,\n", + " 1994, 1995, 1997, 2010, 2024, 2026, 2029, 2037, 2046, 2059, 2060,\n", + " 2072, 2075, 2078, 2082, 2098, 2099, 2107, 2109, 2111, 2119, 2121,\n", + " 2128, 2136, 2152, 2157, 2170, 2171, 2172, 2176, 2192, 2194, 2205,\n", + " 2215, 2217, 2218, 2222, 2223, 2225, 2236, 2242, 2261, 2276, 2277,\n", + " 2279, 2281, 2303, 2307, 2308, 2315, 2322, 2328, 2348, 2353, 2361,\n", + " 2365, 2378, 2383, 2386, 2389, 2390, 2391, 2398, 2406, 2408, 2410,\n", + " 2434, 2436, 2437, 2442, 2444, 2457, 2458, 2460, 2461, 2463, 2467,\n", + " 2480, 2486, 2493, 2497, 2505, 2508, 2510, 2522, 2524, 2526, 2534,\n", + " 2544, 2548, 2549, 2552, 2557, 2561, 2582, 2586, 2590, 2592, 2595,\n", + " 2601, 2606, 2632, 2650, 2652, 2655, 2663, 2665, 2666, 2668, 2669,\n", + " 2672, 2674, 2681, 2687, 2690, 2691, 2693, 2699, 2711, 2720, 2722,\n", + " 2727, 2734, 2745, 2747, 2758, 2759, 2769, 2771, 2772, 2775, 2781,\n", + " 2783, 2787, 2789, 2796, 2810, 2811, 2820, 2827, 2833, 2839, 2840,\n", + " 2842, 2843, 2847, 2853, 2860, 2875, 2876, 2881, 2888, 2894, 2901,\n", + " 2904, 2916, 2919, 2928, 2950, 2954, 2960, 2963, 2966, 2986, 2987,\n", + " 2992, 2994, 2999, 3000, 3007, 3039, 3059, 3061, 3064, 3067, 3073,\n", + " 3078, 3082, 3087, 3088, 3090, 3099, 3104, 3112, 3126, 3127, 3131,\n", + " 3135, 3144, 3149, 3150, 3154, 3155, 3157, 3162, 3170, 3175, 3180,\n", + " 3181, 3182, 3183, 3184, 3187, 3197, 3204, 3210, 3216, 3221, 3225,\n", + " 3227, 3230, 3235, 3236, 3243, 3244, 3271, 3272, 3276, 3278, 3283,\n", + " 3289, 3293, 3304, 3305, 3306, 3307, 3318, 3324, 3329, 3346, 3348,\n", + " 3350, 3352, 3358, 3362, 3383, 3385, 3388, 3405, 3408, 3422, 3437,\n", + " 3439, 3446, 3448, 3450, 3486, 3507, 3512, 3513, 3516, 3522, 3523,\n", + " 3554, 3560, 3569, 3573, 3574, 3584, 3593, 3595, 3601, 3606, 3613,\n", + " 3614])),\n", + " (3,\n", + " array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1.]),\n", + " 19.20965012246301,\n", + " array([ 4, 5, 13, 30, 54, 59, 61, 76, 78, 82, 98,\n", + " 104, 112, 129, 132, 142, 143, 152, 155, 156, 167, 168,\n", + " 180, 181, 185, 203, 209, 222, 225, 239, 245, 251, 258,\n", + " 262, 269, 272, 284, 290, 305, 312, 316, 337, 347, 349,\n", + " 350, 352, 354, 362, 377, 385, 394, 413, 422, 425, 428,\n", + " 429, 439, 440, 441, 447, 448, 453, 459, 463, 464, 488,\n", + " 492, 496, 500, 509, 520, 521, 523, 525, 526, 533, 549,\n", + " 557, 558, 567, 574, 587, 593, 606, 607, 625, 627, 634,\n", + " 655, 663, 667, 674, 679, 683, 696, 718, 719, 729, 748,\n", + " 760, 769, 796, 800, 801, 807, 816, 818, 832, 835, 850,\n", + " 858, 862, 870, 875, 880, 884, 886, 889, 892, 897, 920,\n", + " 940, 944, 954, 958, 979, 985, 988, 991, 1002, 1010, 1027,\n", + " 1028, 1033, 1039, 1041, 1050, 1052, 1053, 1084, 1085, 1098, 1103,\n", + " 1109, 1116, 1122, 1146, 1156, 1163, 1166, 1170, 1190, 1195, 1203,\n", + " 1209, 1215, 1216, 1221, 1237, 1248, 1251, 1265, 1266, 1268, 1274,\n", + " 1298, 1304, 1318, 1322, 1347, 1349, 1377, 1390, 1392, 1404, 1417,\n", + " 1420, 1430, 1433, 1438, 1441, 1443, 1448, 1449, 1457, 1458, 1459,\n", + " 1465, 1476, 1485, 1488, 1502, 1510, 1515, 1523, 1533, 1536, 1538,\n", + " 1558, 1571, 1574, 1579, 1586, 1592, 1593, 1602, 1607, 1623, 1632,\n", + " 1636, 1637, 1638, 1639, 1652, 1670, 1673, 1682, 1683, 1684, 1698,\n", + " 1719, 1735, 1744, 1745, 1752, 1756, 1763, 1768, 1776, 1790, 1795,\n", + " 1796, 1807, 1823, 1830, 1837, 1839, 1840, 1841, 1852, 1877, 1879,\n", + " 1889, 1930, 1939, 1944, 1945, 1959, 1969, 1978, 1985, 1987, 1996,\n", + " 2007, 2014, 2018, 2030, 2043, 2044, 2066, 2081, 2095, 2101, 2105,\n", + " 2108, 2125, 2129, 2137, 2143, 2150, 2153, 2185, 2196, 2206, 2212,\n", + " 2214, 2216, 2231, 2235, 2262, 2272, 2278, 2298, 2310, 2318, 2324,\n", + " 2333, 2343, 2359, 2372, 2381, 2394, 2395, 2400, 2425, 2429, 2446,\n", + " 2462, 2470, 2471, 2472, 2475, 2477, 2484, 2485, 2487, 2488, 2489,\n", + " 2511, 2523, 2538, 2541, 2563, 2568, 2617, 2629, 2644, 2649, 2670,\n", + " 2676, 2683, 2685, 2695, 2696, 2819, 2823, 2825, 2830, 2834, 2838,\n", + " 2846, 2863, 2870, 2883, 2893, 2910, 2912, 2921, 2930, 2931, 2933,\n", + " 2939, 2940, 2942, 2945, 2958, 2971, 2980, 3013, 3015, 3016, 3019,\n", + " 3026, 3027, 3049, 3050, 3060, 3076, 3086, 3092, 3093, 3094, 3096,\n", + " 3100, 3110, 3115, 3120, 3130, 3133, 3136, 3141, 3143, 3159, 3165,\n", + " 3186, 3191, 3195, 3198, 3202, 3211, 3215, 3222, 3223, 3228, 3229,\n", + " 3234, 3248, 3257, 3258, 3280, 3281, 3286, 3291, 3314, 3317, 3325,\n", + " 3327, 3340, 3355, 3368, 3370, 3387, 3395, 3402, 3407, 3414, 3417,\n", + " 3420, 3428, 3435, 3451, 3454, 3455, 3464, 3479, 3487, 3491, 3493,\n", + " 3495, 3535, 3558, 3564, 3590, 3592, 3607, 3610, 3612, 3615, 3619,\n", + " 3620, 3624])),\n", + " (4,\n", + " array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.]),\n", + " 23.6344423140483,\n", + " array([ 17, 23, 24, 36, 37, 39, 40, 50, 62, 66, 67,\n", + " 75, 81, 91, 92, 100, 119, 125, 158, 162, 166, 176,\n", + " 186, 191, 195, 200, 208, 210, 220, 233, 237, 244, 250,\n", + " 257, 259, 263, 273, 293, 294, 314, 319, 322, 330, 344,\n", + " 348, 353, 360, 387, 401, 402, 461, 468, 475, 478, 482,\n", + " 493, 494, 495, 498, 501, 506, 511, 515, 518, 528, 541,\n", + " 556, 561, 577, 578, 601, 611, 612, 615, 618, 620, 623,\n", + " 640, 645, 656, 664, 666, 681, 688, 691, 694, 699, 710,\n", + " 711, 722, 723, 724, 733, 734, 745, 755, 764, 770, 771,\n", + " 777, 790, 794, 799, 803, 812, 830, 836, 841, 843, 849,\n", + " 852, 860, 879, 882, 885, 900, 909, 919, 926, 933, 936,\n", + " 943, 951, 956, 961, 964, 980, 983, 992, 1007, 1012, 1013,\n", + " 1029, 1034, 1047, 1048, 1051, 1054, 1056, 1058, 1061, 1064, 1080,\n", + " 1081, 1086, 1087, 1088, 1091, 1092, 1095, 1111, 1113, 1119, 1121,\n", + " 1125, 1126, 1127, 1145, 1149, 1150, 1164, 1167, 1176, 1181, 1205,\n", + " 1207, 1208, 1219, 1228, 1235, 1236, 1239, 1240, 1250, 1264, 1276,\n", + " 1299, 1300, 1303, 1306, 1311, 1314, 1328, 1332, 1342, 1351, 1363,\n", + " 1370, 1371, 1376, 1380, 1386, 1387, 1398, 1399, 1403, 1422, 1423,\n", + " 1435, 1437, 1439, 1442, 1447, 1467, 1470, 1472, 1479, 1489, 1492,\n", + " 1499, 1504, 1508, 1514, 1526, 1537, 1547, 1551, 1555, 1561, 1562,\n", + " 1564, 1575, 1596, 1608, 1611, 1612, 1635, 1641, 1675, 1676, 1678,\n", + " 1681, 1693, 1694, 1695, 1696, 1697, 1700, 1703, 1714, 1721, 1722,\n", + " 1723, 1732, 1747, 1753, 1758, 1759, 1761, 1765, 1774, 1805, 1819,\n", + " 1844, 1845, 1846, 1847, 1849, 1871, 1881, 1885, 1892, 1898, 1908,\n", + " 1910, 1927, 1928, 1949, 1950, 1961, 1967, 1977, 1982, 1983, 1986,\n", + " 1989, 1990, 2011, 2019, 2020, 2023, 2040, 2042, 2045, 2050, 2054,\n", + " 2057, 2058, 2085, 2087, 2097, 2100, 2106, 2110, 2123, 2130, 2141,\n", + " 2151, 2158, 2163, 2179, 2187, 2193, 2195, 2197, 2202, 2207, 2208,\n", + " 2227, 2237, 2238, 2244, 2256, 2258, 2263, 2287, 2299, 2319, 2325,\n", + " 2326, 2329, 2330, 2336, 2340, 2345, 2384, 2387, 2401, 2414, 2416,\n", + " 2426, 2427, 2431, 2433, 2452, 2456, 2459, 2468, 2483, 2492, 2494,\n", + " 2496, 2500, 2504, 2512, 2515, 2516, 2520, 2525, 2540, 2560, 2566,\n", + " 2567, 2570, 2571, 2581, 2599, 2605, 2613, 2616, 2630, 2634, 2635,\n", + " 2637, 2641, 2645, 2653, 2656, 2657, 2675, 2678, 2709, 2725, 2737,\n", + " 2753, 2760, 2762, 2763, 2784, 2797, 2800, 2801, 2808, 2815, 2832,\n", + " 2837, 2844, 2845, 2851, 2868, 2880, 2886, 2887, 2897, 2899, 2905,\n", + " 2915, 2925, 2937, 2938, 2944, 2947, 2951, 2952, 2956, 2961, 2968,\n", + " 2977, 2991, 3004, 3038, 3058, 3065, 3068, 3070, 3071, 3075, 3097,\n", + " 3102, 3105, 3109, 3117, 3119, 3123, 3140, 3152, 3161, 3163, 3164,\n", + " 3167, 3176, 3194, 3196, 3200, 3207, 3212, 3219, 3224, 3255, 3274,\n", + " 3277, 3279, 3284, 3285, 3295, 3297, 3299, 3300, 3308, 3310, 3321,\n", + " 3322, 3323, 3333, 3334, 3337, 3338, 3343, 3344, 3354, 3364, 3372,\n", + " 3378, 3384, 3394, 3409, 3411, 3416, 3427, 3438, 3440, 3441, 3449,\n", + " 3463, 3469, 3475, 3476, 3484, 3485, 3508, 3509, 3511, 3528, 3531,\n", + " 3539, 3542, 3555, 3561, 3603, 3608, 3622])),\n", + " (5,\n", + " array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.]),\n", + " 16.251921424887335,\n", + " array([ 12, 14, 15, 35, 45, 49, 51, 63, 65, 68, 79,\n", + " 105, 139, 141, 147, 150, 153, 154, 178, 217, 219, 231,\n", + " 236, 238, 254, 264, 274, 277, 288, 301, 306, 326, 328,\n", + " 329, 346, 355, 358, 364, 365, 371, 375, 378, 379, 384,\n", + " 389, 390, 391, 396, 411, 427, 431, 444, 477, 481, 491,\n", + " 517, 543, 544, 555, 588, 594, 608, 616, 628, 639, 643,\n", + " 662, 671, 682, 703, 752, 775, 782, 784, 788, 793, 798,\n", + " 811, 827, 828, 845, 864, 869, 898, 913, 921, 938, 949,\n", + " 953, 962, 966, 972, 977, 987, 996, 1003, 1004, 1008, 1019,\n", + " 1023, 1038, 1042, 1049, 1068, 1069, 1074, 1076, 1078, 1089, 1102,\n", + " 1105, 1128, 1153, 1155, 1162, 1179, 1182, 1198, 1211, 1212, 1217,\n", + " 1218, 1225, 1231, 1232, 1241, 1245, 1257, 1262, 1269, 1270, 1281,\n", + " 1286, 1294, 1297, 1309, 1312, 1323, 1327, 1339, 1341, 1360, 1378,\n", + " 1383, 1388, 1389, 1400, 1401, 1413, 1416, 1450, 1455, 1463, 1477,\n", + " 1484, 1494, 1495, 1505, 1506, 1522, 1534, 1544, 1549, 1550, 1554,\n", + " 1569, 1572, 1588, 1598, 1613, 1622, 1626, 1630, 1644, 1666, 1669,\n", + " 1686, 1708, 1724, 1727, 1737, 1743, 1749, 1771, 1793, 1799, 1801,\n", + " 1803, 1808, 1814, 1817, 1835, 1853, 1868, 1872, 1895, 1896, 1912,\n", + " 1914, 1916, 1922, 1931, 1933, 1946, 1974, 1992, 2005, 2033, 2052,\n", + " 2053, 2062, 2069, 2073, 2074, 2089, 2091, 2094, 2103, 2113, 2116,\n", + " 2122, 2127, 2135, 2149, 2154, 2162, 2164, 2166, 2180, 2181, 2182,\n", + " 2209, 2211, 2245, 2253, 2257, 2268, 2271, 2288, 2290, 2296, 2316,\n", + " 2334, 2337, 2338, 2339, 2341, 2347, 2349, 2351, 2355, 2356, 2405,\n", + " 2413, 2422, 2428, 2438, 2440, 2448, 2455, 2464, 2473, 2479, 2482,\n", + " 2490, 2509, 2517, 2531, 2550, 2555, 2558, 2574, 2575, 2583, 2589,\n", + " 2591, 2597, 2611, 2614, 2618, 2627, 2633, 2636, 2643, 2682, 2700,\n", + " 2704, 2707, 2716, 2721, 2726, 2754, 2764, 2765, 2793, 2794, 2805,\n", + " 2814, 2835, 2852, 2855, 2856, 2862, 2866, 2878, 2891, 2909, 2918,\n", + " 2920, 2924, 2974, 2982, 2993, 3011, 3020, 3022, 3040, 3041, 3044,\n", + " 3054, 3056, 3091, 3101, 3107, 3108, 3111, 3142, 3151, 3156, 3203,\n", + " 3206, 3213, 3217, 3231, 3269, 3309, 3313, 3331, 3332, 3335, 3342,\n", + " 3349, 3359, 3374, 3389, 3400, 3403, 3445, 3453, 3460, 3467, 3492,\n", + " 3498, 3500, 3515, 3521, 3525, 3526, 3529, 3543, 3568, 3571, 3585,\n", + " 3588, 3589, 3591, 3594, 3604]))]" + ] + }, + "execution_count": 81, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# here the information for all the combinations\n", + "freq_wrap.iter_columns()" + ] + }, + { + "cell_type": "code", + "execution_count": 82, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(0,\n", + " array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.]),\n", + " 46.529753144154704,\n", + " array([ 0, 1, 2, 7, 16, 18, 20, 27, 32, 34, 38,\n", + " 41, 47, 58, 60, 74, 84, 86, 87, 88, 90, 95,\n", + " 97, 99, 106, 107, 108, 115, 116, 118, 121, 122, 130,\n", + " 131, 135, 138, 140, 159, 163, 165, 169, 175, 182, 190,\n", + " 192, 205, 207, 211, 212, 214, 215, 221, 223, 226, 227,\n", + " 228, 229, 232, 235, 240, 242, 256, 261, 268, 270, 279,\n", + " 280, 281, 282, 283, 285, 287, 291, 295, 297, 298, 299,\n", + " 300, 308, 309, 310, 311, 315, 320, 324, 331, 332, 336,\n", + " 338, 345, 356, 361, 363, 366, 367, 368, 372, 380, 383,\n", + " 388, 393, 400, 403, 406, 408, 418, 419, 430, 432, 433,\n", + " 434, 449, 450, 465, 466, 471, 472, 473, 483, 486, 499,\n", + " 504, 513, 514, 519, 537, 538, 540, 545, 546, 548, 552,\n", + " 553, 559, 565, 573, 579, 580, 583, 585, 589, 590, 597,\n", + " 598, 609, 613, 622, 624, 629, 632, 635, 636, 637, 638,\n", + " 641, 642, 646, 649, 650, 660, 661, 669, 672, 673, 684,\n", + " 687, 692, 697, 698, 706, 713, 716, 725, 727, 737, 738,\n", + " 739, 741, 747, 751, 754, 761, 762, 768, 797, 804, 805,\n", + " 809, 814, 815, 820, 822, 824, 825, 826, 837, 839, 840,\n", + " 842, 847, 855, 863, 866, 868, 872, 876, 887, 891, 901,\n", + " 905, 911, 916, 917, 923, 937, 939, 942, 945, 946, 952,\n", + " 960, 967, 969, 970, 973, 974, 975, 978, 984, 989, 990,\n", + " 993, 997, 999, 1000, 1005, 1006, 1009, 1011, 1015, 1021, 1022,\n", + " 1024, 1031, 1037, 1040, 1043, 1044, 1057, 1059, 1062, 1063, 1071,\n", + " 1072, 1073, 1079, 1083, 1090, 1093, 1094, 1096, 1097, 1101, 1106,\n", + " 1107, 1108, 1114, 1118, 1124, 1130, 1137, 1138, 1140, 1143, 1144,\n", + " 1161, 1171, 1175, 1178, 1180, 1186, 1187, 1188, 1192, 1196, 1197,\n", + " 1204, 1226, 1247, 1252, 1253, 1254, 1256, 1259, 1261, 1263, 1267,\n", + " 1271, 1279, 1285, 1292, 1295, 1302, 1305, 1308, 1317, 1319, 1321,\n", + " 1324, 1331, 1333, 1335, 1354, 1355, 1357, 1358, 1361, 1362, 1366,\n", + " 1367, 1373, 1382, 1395, 1396, 1397, 1406, 1407, 1408, 1409, 1415,\n", + " 1421, 1425, 1426, 1427, 1429, 1434, 1444, 1445, 1452, 1456, 1460,\n", + " 1461, 1466, 1474, 1480, 1481, 1482, 1490, 1491, 1493, 1501, 1509,\n", + " 1521, 1528, 1545, 1552, 1566, 1567, 1570, 1576, 1577, 1580, 1582,\n", + " 1594, 1603, 1605, 1618, 1619, 1627, 1628, 1643, 1645, 1650, 1653,\n", + " 1654, 1655, 1657, 1660, 1661, 1662, 1664, 1674, 1679, 1688, 1691,\n", + " 1692, 1701, 1704, 1705, 1709, 1710, 1711, 1712, 1713, 1715, 1729,\n", + " 1730, 1731, 1738, 1739, 1741, 1746, 1751, 1766, 1770, 1779, 1783,\n", + " 1785, 1787, 1800, 1802, 1811, 1816, 1820, 1821, 1824, 1829, 1833,\n", + " 1843, 1848, 1850, 1851, 1856, 1861, 1865, 1866, 1867, 1870, 1874,\n", + " 1875, 1878, 1883, 1887, 1890, 1891, 1893, 1897, 1903, 1904, 1905,\n", + " 1907, 1917, 1918, 1920, 1923, 1924, 1932, 1934, 1937, 1947, 1953,\n", + " 1957, 1958, 1962, 1965, 1971, 1972, 1975, 1976, 1979, 1980, 1998,\n", + " 2000, 2003, 2008, 2013, 2021, 2025, 2028, 2032, 2034, 2036, 2041,\n", + " 2048, 2049, 2056, 2061, 2064, 2068, 2070, 2076, 2080, 2086, 2090,\n", + " 2093, 2096, 2102, 2112, 2120, 2124, 2131, 2132, 2133, 2138, 2144,\n", + " 2146, 2159, 2165, 2167, 2173, 2174, 2183, 2184, 2189, 2198, 2200,\n", + " 2203, 2204, 2210, 2213, 2219, 2220, 2228, 2233, 2234, 2240, 2241,\n", + " 2251, 2252, 2255, 2260, 2264, 2265, 2267, 2273, 2280, 2283, 2284,\n", + " 2285, 2286, 2289, 2291, 2293, 2294, 2295, 2297, 2309, 2313, 2314,\n", + " 2317, 2321, 2331, 2335, 2344, 2350, 2352, 2364, 2369, 2370, 2371,\n", + " 2380, 2393, 2396, 2402, 2403, 2404, 2411, 2412, 2415, 2423, 2435,\n", + " 2445, 2447, 2450, 2453, 2466, 2469, 2476, 2481, 2491, 2495, 2507,\n", + " 2513, 2514, 2518, 2519, 2527, 2530, 2532, 2535, 2536, 2539, 2542,\n", + " 2545, 2546, 2547, 2559, 2562, 2565, 2577, 2579, 2584, 2588, 2593,\n", + " 2594, 2596, 2598, 2603, 2604, 2610, 2612, 2615, 2621, 2622, 2623,\n", + " 2631, 2638, 2642, 2646, 2647, 2654, 2659, 2660, 2661, 2662, 2667,\n", + " 2671, 2677, 2684, 2686, 2688, 2689, 2692, 2694, 2701, 2702, 2703,\n", + " 2705, 2706, 2712, 2714, 2715, 2717, 2719, 2724, 2728, 2729, 2735,\n", + " 2739, 2742, 2744, 2748, 2750, 2755, 2757, 2768, 2770, 2773, 2774,\n", + " 2776, 2777, 2778, 2779, 2780, 2785, 2790, 2791, 2792, 2802, 2803,\n", + " 2806, 2812, 2818, 2824, 2828, 2829, 2831, 2848, 2849, 2857, 2858,\n", + " 2861, 2864, 2872, 2874, 2877, 2882, 2884, 2885, 2890, 2898, 2900,\n", + " 2902, 2906, 2911, 2913, 2922, 2926, 2934, 2935, 2943, 2953, 2955,\n", + " 2964, 2967, 2969, 2972, 2973, 2981, 2983, 2984, 2985, 2988, 2990,\n", + " 2996, 2997, 3002, 3009, 3010, 3012, 3024, 3025, 3030, 3035, 3036,\n", + " 3043, 3045, 3047, 3052, 3053, 3055, 3062, 3069, 3072, 3077, 3079,\n", + " 3080, 3084, 3089, 3095, 3098, 3116, 3118, 3124, 3128, 3138, 3145,\n", + " 3148, 3166, 3168, 3173, 3174, 3178, 3185, 3193, 3205, 3208, 3214,\n", + " 3218, 3232, 3237, 3240, 3247, 3256, 3259, 3262, 3263, 3266, 3267,\n", + " 3270, 3273, 3287, 3294, 3296, 3301, 3302, 3311, 3316, 3320, 3336,\n", + " 3341, 3345, 3353, 3356, 3357, 3363, 3365, 3366, 3367, 3369, 3371,\n", + " 3376, 3377, 3380, 3390, 3391, 3393, 3397, 3399, 3401, 3404, 3406,\n", + " 3410, 3415, 3419, 3421, 3424, 3429, 3431, 3432, 3443, 3444, 3457,\n", + " 3458, 3459, 3462, 3466, 3468, 3470, 3471, 3472, 3473, 3478, 3488,\n", + " 3490, 3494, 3497, 3499, 3503, 3505, 3520, 3532, 3544, 3546, 3547,\n", + " 3548, 3550, 3551, 3556, 3557, 3562, 3567, 3570, 3576, 3578, 3581,\n", + " 3582, 3596, 3611, 3616, 3617, 3618, 3623]))" + ] + }, + "execution_count": 82, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# and here, we can see for category \"0\" that non zero values are...\n", + "freq_wrap.get_column(0)" + ] + }, + { + "cell_type": "code", + "execution_count": 83, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "hh_id\n", + "0 1.0\n", + "2 1.0\n", + "3 1.0\n", + "4 0.0\n", + "5 0.0\n", + "13 0.0\n", + "14 0.0\n", + "15 1.0\n", + "Name: 0, dtype: float64" + ] + }, + "execution_count": 83, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "#... in the index 0, 1, 2, 7, (...)\n", + "h_freq_table[0][0:8]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "With this wrapper, we build the fit quality od each `cat_id`" + ] + }, + { + "cell_type": "code", + "execution_count": 84, + "metadata": {}, + "outputs": [], + "source": [ + "from synthpop.ipu.ipu import _average_fit_quality\n", + "from synthpop.ipu.ipu import _fit_quality" + ] + }, + { + "cell_type": "code", + "execution_count": 85, + "metadata": {}, + "outputs": [], + "source": [ + "# weights matrix\n", + "weights = np.ones(len(h_freq_table), dtype='float')\n", + "\n", + "# column (this is the non-zero elements of the \"0\" cat_id column of the frequency table)\n", + "cat_id_0_column = [e for e in freq_wrap.get_column(0)][1]\n", + "\n", + "# nz (this is the idx of the frequency table where non zero values are stored)\n", + "cat_id_0_nz = [e for e in freq_wrap.get_column(0)][3]" + ] + }, + { + "cell_type": "code", + "execution_count": 86, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 86, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# the non zero values should have the same length when filtering the weights matrix\n", + "len(cat_id_0_column) == len(weights[cat_id_0_nz])" + ] + }, + { + "cell_type": "code", + "execution_count": 87, + "metadata": {}, + "outputs": [], + "source": [ + "# the new target value for the block group\n", + "constraint = [e for e in freq_wrap.get_column(0)][2]" + ] + }, + { + "cell_type": "code", + "execution_count": 88, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "17.11743976780375" + ] + }, + "execution_count": 88, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# this is the \"fit quality\" value for cat_id \"0\"\n", + "_fit_quality(cat_id_0_column, weights[cat_id_0_nz], constraint)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This value is the result of multiplying the non-zero values by the weights matrix, which returns the total frequency of the category within the PUMA: " + ] + }, + { + "cell_type": "code", + "execution_count": 89, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "843.0" + ] + }, + "execution_count": 89, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "(cat_id_0_column * weights[cat_id_0_nz]).sum()" + ] + }, + { + "cell_type": "code", + "execution_count": 90, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
cat_idfrequency
hh_carshh_children
noneno0843
yes1919
oneno2573
yes3431
two or moreno4491
yes5368
\n", + "
" + ], + "text/plain": [ + " cat_id frequency\n", + "hh_cars hh_children \n", + "none no 0 843\n", + " yes 1 919\n", + "one no 2 573\n", + " yes 3 431\n", + "two or more no 4 491\n", + " yes 5 368" + ] + }, + "execution_count": 90, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Here the total households with no car and no children(843)\n", + "jd_households" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The sum of non zero values is weighted and then reduced by substracting the constraints..." + ] + }, + { + "cell_type": "code", + "execution_count": 91, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "796.4702468558453" + ] + }, + "execution_count": 91, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "(cat_id_0_column * weights[cat_id_0_nz]).sum() - constraint" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "... and finally is expressed in terms of the constraint for that category - the 𝛿 parameter described in the IPU paper -. The absolute value of the relative difference between the weighted sum and the corresponding constraint may be used as a goodness of fit measure and is defined as: " + ] + }, + { + "cell_type": "code", + "execution_count": 92, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "17.11743976780375" + ] + }, + "execution_count": 92, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "((cat_id_0_column * weights[cat_id_0_nz]).sum() - constraint) / constraint" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This is basically showing the proportion of the `cat_id` within the entire population of the PUMA. In the example of this first iteration, we have that for each household that `cat_id` == `0`, there are 17 households that could be out of that category (`cat_id` != `0`). " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "![constraints](img/ipu.png)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This process will be repeated for all household types (or `cat_id`) and build a unique average value (which is the sum of each `_fit_quality` result divided by the number of `cat_id` columns):" + ] + }, + { + "cell_type": "code", + "execution_count": 93, + "metadata": {}, + "outputs": [], + "source": [ + "fit_qual_0_to_5 = _average_fit_quality(freq_wrap, weights)" + ] + }, + { + "cell_type": "code", + "execution_count": 94, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "19.71740696516147" + ] + }, + "execution_count": 94, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "fit_qual_0_to_5" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "As it is explained on [A METHODOLOGY TO MATCH DISTRIBUTIONS OF BOTH HOUSEHOLD AND\n", + "PERSON ATTRIBUTES IN THE GENERATION OF SYNTHETIC POPULATIONS ](http://www.scag.ca.gov/Documents/PopulationSynthesizerPaper_TRB.pdf), the IPU algorithm starts by assuming equal weights for all households in the sample. The algorithm then proceeds by adjusting weights for each household/person constraint in an iterative process until the constraints are matched as closely as possible for both household and person attributes. " + ] + }, + { + "cell_type": "code", + "execution_count": 95, + "metadata": {}, + "outputs": [], + "source": [ + "fit_change = np.inf\n", + "convergence= 1e-4" + ] + }, + { + "cell_type": "code", + "execution_count": 96, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Updating weights matrix until reaching a fit quality value under the convergence!\n" + ] + } + ], + "source": [ + "if fit_change > convergence:\n", + " print(\"Updating weights matrix until reaching a fit quality value under the convergence!\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The weights for the each household level constraint are adjusted by dividing the number of households in that category (i.e., the constraint value) by the weighted sum of the first household type column: \n", + "\n", + "The `_update_weights` creates the following adjustment `adj = constraint / float((column * weights).sum())` and use it to update weights (`weights * adj`). The weights for all households of each household type will be multiplied by this ratio to satisfy the constraint. " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In this sense, the `households_weights` function will finally return a:" + ] + }, + { + "cell_type": "code", + "execution_count": 97, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "hh_id\n", + "0 0.055195\n", + "2 0.055195\n", + "3 0.055195\n", + "4 0.050640\n", + "5 0.044570\n", + " ... \n", + "5857 0.044570\n", + "5858 0.050640\n", + "5862 0.048135\n", + "5865 0.055195\n", + "5868 0.044570\n", + "Length: 3625, dtype: float64" + ] + }, + "execution_count": 97, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# 1. An array of corrected weights that best matches each household type \n", + "best_weights" + ] + }, + { + "cell_type": "code", + "execution_count": 98, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "1.636802750002612e-16" + ] + }, + "execution_count": 98, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# 2. And a fit quality based on the proportion of each hh type that reduces the fit changes under the convergence \n", + "fit_quality" + ] + }, + { + "cell_type": "code", + "execution_count": 99, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "2" + ] + }, + "execution_count": 99, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# 3. Built in ...\n", + "iterations" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 4. Drawing synthetic population " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "![draw](img/draw.png)" + ] + }, + { + "cell_type": "code", + "execution_count": 100, + "metadata": {}, + "outputs": [], + "source": [ + "from synthpop import draw" + ] + }, + { + "cell_type": "code", + "execution_count": 101, + "metadata": {}, + "outputs": [], + "source": [ + "num_households = int(hh_marginals_tract_400_block_gp_1.groupby(level=0).sum().mean())" + ] + }, + { + "cell_type": "code", + "execution_count": 102, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "178" + ] + }, + "execution_count": 102, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "num_households" + ] + }, + { + "cell_type": "code", + "execution_count": 103, + "metadata": {}, + "outputs": [], + "source": [ + "fac = _FrequencyAndConstraints(h_freq_table, h_constraint)" + ] + }, + { + "cell_type": "code", + "execution_count": 104, + "metadata": {}, + "outputs": [], + "source": [ + "indexes = draw._draw_indexes(num_households, fac, best_weights)" + ] + }, + { + "cell_type": "code", + "execution_count": 105, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Int64Index([1093, 3079, 5129, 2804, 987, 1928, 5717, 5465, 5675, 4820,\n", + " ...\n", + " 3483, 329, 1902, 3312, 4611, 4939, 1862, 590, 4364, 5444],\n", + " dtype='int64', length=178)" + ] + }, + "execution_count": 105, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "indexes" + ] + }, + { + "cell_type": "code", + "execution_count": 106, + "metadata": {}, + "outputs": [], + "source": [ + "synth_hh = h_pums.loc[indexes].reset_index(drop=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 107, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
serialnoRTpuma00puma10NPTYPEBLDTENVEHHINCPMVR18R65hh_carshh_childrencat_id
02012001216090H-9400112.04.00.06500.01.00.00.0noneno0
12009000613417H400-9112.02.00.012850.07.00.00.0noneno0
22011000710483H400-9112.03.00.060000.02.00.00.0noneno0
32009000187197H400-9112.02.00.019100.06.00.01.0noneno0
42012001104421H-9400212.04.00.046430.06.00.00.0noneno0
...................................................
1732011000489471H400-9712.03.02.036600.03.01.00.0two or moreyes5
1742013000550452H-9400412.02.02.054100.05.01.00.0two or moreyes5
1752012000679081H-9400612.01.04.0116160.02.01.00.0two or moreyes5
1762010001169426H400-9812.01.03.0103000.06.01.00.0two or moreyes5
1772011001034440H400-9215.03.01.051000.03.00.00.0oneno2
\n", + "

178 rows × 16 columns

\n", + "
" + ], + "text/plain": [ + " serialno RT puma00 puma10 NP TYPE BLD TEN VEH HINCP MV \\\n", + "0 2012001216090 H -9 400 1 1 2.0 4.0 0.0 6500.0 1.0 \n", + "1 2009000613417 H 400 -9 1 1 2.0 2.0 0.0 12850.0 7.0 \n", + "2 2011000710483 H 400 -9 1 1 2.0 3.0 0.0 60000.0 2.0 \n", + "3 2009000187197 H 400 -9 1 1 2.0 2.0 0.0 19100.0 6.0 \n", + "4 2012001104421 H -9 400 2 1 2.0 4.0 0.0 46430.0 6.0 \n", + ".. ... .. ... ... .. ... ... ... ... ... ... \n", + "173 2011000489471 H 400 -9 7 1 2.0 3.0 2.0 36600.0 3.0 \n", + "174 2013000550452 H -9 400 4 1 2.0 2.0 2.0 54100.0 5.0 \n", + "175 2012000679081 H -9 400 6 1 2.0 1.0 4.0 116160.0 2.0 \n", + "176 2010001169426 H 400 -9 8 1 2.0 1.0 3.0 103000.0 6.0 \n", + "177 2011001034440 H 400 -9 2 1 5.0 3.0 1.0 51000.0 3.0 \n", + "\n", + " R18 R65 hh_cars hh_children cat_id \n", + "0 0.0 0.0 none no 0 \n", + "1 0.0 0.0 none no 0 \n", + "2 0.0 0.0 none no 0 \n", + "3 0.0 1.0 none no 0 \n", + "4 0.0 0.0 none no 0 \n", + ".. ... ... ... ... ... \n", + "173 1.0 0.0 two or more yes 5 \n", + "174 1.0 0.0 two or more yes 5 \n", + "175 1.0 0.0 two or more yes 5 \n", + "176 1.0 0.0 two or more yes 5 \n", + "177 0.0 0.0 one no 2 \n", + "\n", + "[178 rows x 16 columns]" + ] + }, + "execution_count": 107, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "synth_hh" + ] + }, { "cell_type": "code", - "execution_count": null, + "execution_count": 108, "metadata": {}, "outputs": [], + "source": [ + "mrg_tbl = pd.DataFrame(\n", + " {'serialno': synth_hh.serialno.values,\n", + " 'hh_id': synth_hh.index.values})" + ] + }, + { + "cell_type": "code", + "execution_count": 109, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
serialnohh_id
020120012160900
120090006134171
220110007104832
320090001871973
420120011044214
.........
1732011000489471173
1742013000550452174
1752012000679081175
1762010001169426176
1772011001034440177
\n", + "

178 rows × 2 columns

\n", + "
" + ], + "text/plain": [ + " serialno hh_id\n", + "0 2012001216090 0\n", + "1 2009000613417 1\n", + "2 2011000710483 2\n", + "3 2009000187197 3\n", + "4 2012001104421 4\n", + ".. ... ...\n", + "173 2011000489471 173\n", + "174 2013000550452 174\n", + "175 2012000679081 175\n", + "176 2010001169426 176\n", + "177 2011001034440 177\n", + "\n", + "[178 rows x 2 columns]" + ] + }, + "execution_count": 109, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "mrg_tbl" ]