In [1]:
%load_ext autoreload
%autoreload 2
from synthpop.census_helpers import Census
from synthpop import categorizer as cat
import pandas as pd
import numpy as np
import os
pd.set_option('display.max_columns', 500)

The census api needs a key - you can register for can sign up


In [2]:
c = Census(os.environ["CENSUS"])

Here we get aggregate information on households from ACS - note some variables are associated with block groups and others with tracts


In [3]:
income_columns = ['B19001_0%02dE'%i for i in range(1, 18)]
vehicle_columns = ['B08201_0%02dE'%i for i in range(1, 7)]
workers_columns = ['B08202_0%02dE'%i for i in range(1, 6)]
families_columns = ['B11001_001E', 'B11001_002E']
block_group_columns = income_columns + families_columns
tract_columns = vehicle_columns + workers_columns
h_acs = c.block_group_and_tract_query(block_group_columns,
                tract_columns, "06", "075", 
                merge_columns=['tract', 'county', 'state'],
                block_group_size_attr="B11001_001E",
                tract_size_attr="B08201_001E",
                tract="030600")
h_acs


Out[3]:
B11001_001E B11001_002E B19001_001E B19001_002E B19001_003E B19001_004E B19001_005E B19001_006E B19001_007E B19001_008E B19001_009E B19001_010E B19001_011E B19001_012E B19001_013E B19001_014E B19001_015E B19001_016E B19001_017E NAME block group county state tract B08201_001E B08201_002E B08201_003E B08201_004E B08201_005E B08201_006E B08202_001E B08202_002E B08202_003E B08202_004E B08202_005E
0 294 183 294 0 4 8 28 0 8 0 0 0 27 10 36 33 28 34 78 Block Group 1, Census Tract 306, San Francisco... 1 075 06 030600 294 14 86 125 55 12 294 65 89 118 20
1 226 138 226 0 11 10 9 0 20 0 0 0 9 11 0 25 19 31 81 Block Group 2, Census Tract 306, San Francisco... 2 075 06 030600 226 11 66 96 42 9 226 50 68 91 15
2 287 237 287 3 0 0 8 20 22 0 0 21 7 0 12 22 6 89 77 Block Group 3, Census Tract 306, San Francisco... 3 075 06 030600 287 14 84 122 53 12 287 64 87 115 19

3 rows × 35 columns

And here is aggregate information on people from ACS


In [4]:
population = ['B01001_001E']
sex = ['B01001_002E', 'B01001_026E']
race = ['B02001_0%02dE'%i for i in range(1,11)]
male_age_columns = ['B01001_0%02dE'%i for i in range(3,26)]
female_age_columns = ['B01001_0%02dE'%i for i in range(27,50)]
all_columns = population + sex + race + male_age_columns + female_age_columns
p_acs = c.block_group_query(all_columns, "06", "075", tract="030600")
p_acs


Out[4]:
B01001_001E B01001_002E B01001_003E B01001_004E B01001_005E B01001_006E B01001_007E B01001_008E B01001_009E B01001_010E B01001_011E B01001_012E B01001_013E B01001_014E B01001_015E B01001_016E B01001_017E B01001_018E B01001_019E B01001_020E B01001_021E B01001_022E B01001_023E B01001_024E B01001_025E B01001_026E B01001_027E B01001_028E B01001_029E B01001_030E B01001_031E B01001_032E B01001_033E B01001_034E B01001_035E B02001_001E B02001_002E B02001_003E B02001_004E B02001_005E B02001_006E B02001_007E B02001_008E B02001_009E B02001_010E NAME block group county state tract B01001_036E B01001_037E B01001_038E B01001_039E B01001_040E B01001_041E B01001_042E B01001_043E B01001_044E B01001_045E B01001_046E B01001_047E B01001_048E B01001_049E
0 655 321 8 11 8 0 0 0 0 8 0 48 28 21 51 18 38 4 0 0 39 23 12 0 4 334 46 33 23 0 0 0 0 0 0 655 423 11 0 187 0 12 22 0 22 Block Group 1, Census Tract 306, San Francisco... 1 075 06 030600 6 20 65 41 0 14 7 0 23 0 37 4 0 15
1 528 236 7 17 11 0 4 0 0 0 0 0 14 53 39 24 12 19 9 0 17 8 2 0 0 292 48 7 0 0 3 0 0 25 0 528 448 9 0 11 0 0 60 0 60 Block Group 2, Census Tract 306, San Francisco... 2 075 06 030600 9 40 17 41 10 38 18 0 7 0 9 11 9 0
2 858 493 22 44 0 44 0 0 11 0 6 44 57 50 43 38 38 0 10 21 15 20 10 20 0 365 0 0 49 31 13 0 0 3 0 858 623 11 0 218 0 0 6 0 6 Block Group 3, Census Tract 306, San Francisco... 3 075 06 030600 14 0 51 38 66 30 2 8 7 0 20 9 21 3

3 rows × 64 columns

Get the puma for our test tracts - this actually downloads the mapping file from the census website so it might take a few seconds


In [5]:
puma = c.tract_to_pums("06", "075", "030600")

Download PUMS for people records for a PUMA from our server (we processed the large files into smaller ones for you)


In [6]:
p_pums = c.download_population_pums("06", puma)
p_pums.head(5)


Out[6]:
Unnamed: 0 serialno RT SPORDER PUMA00 PUMA10 ST ADJINC PWGTP AGEP CIT CITWP05 CITWP12 COW DDRS DEAR DEYE DOUT DPHY DRAT DRATX DREM ENG FER GCL GCM GCR HINS1 HINS2 HINS3 HINS4 HINS5 HINS6 HINS7 INTP JWMNP JWRIP JWTR LANX MAR MARHD MARHM MARHT MARHW MARHYP05 MARHYP12 MIG MIL MLPA MLPB MLPC MLPD MLPE MLPF MLPG MLPH MLPI MLPJ MLPK NWAB NWAV NWLA NWLK NWRE OIP PAP RELP RETP SCH SCHG SCHL SEMP SEX SSIP SSP WAGP WKHP WKL WKW YOEP05 YOEP12 ANC ANC1P05 ANC1P12 ANC2P05 ANC2P12 DECADE DIS DRIVESP ESP ESR HICOV HISP INDP JWAP JWDP LANP05 LANP12 MIGPUMA00 MIGPUMA10 MIGSP05 MIGSP12 MSP NAICSP NATIVITY NOP OC OCCP02 OCCP10 OCCP12 PAOC PERNP PINCP POBP05 POBP12 POVPIP POWPUMA00 POWPUMA10 POWSP05 POWSP12 PRIVCOV PUBCOV QTRBIR RAC1P RAC2P05 RAC2P12 RAC3P05 RAC3P12 RACAIAN RACASN RACBLK RACNHPI RACNUM RACSOR RACWHT RC SFN SFR SOCP00 SOCP10 SOCP12 VPS WAOB FAGEP FANCP FCITP FCITWP FCOWP FDDRSP FDEARP FDEYEP FDOUTP FDPHYP FDRATP FDRATXP FDREMP FENGP FESRP FFERP FGCLP FGCMP FGCRP FHINS1P FHINS2P FHINS3C FHINS3P FHINS4C FHINS4P FHINS5C FHINS5P FHINS6P FHINS7P FHISP FINDP FINTP FJWDP FJWMNP FJWRIP FJWTRP FLANP FLANXP FMARHDP FMARHMP FMARHTP FMARHWP FMARHYP FMARP FMIGP FMIGSP FMILPP FMILSP FOCCP FOIP FPAP FPOBP FPOWSP FRACP FRELP FRETP FSCHGP FSCHLP FSCHP FSEMP FSEXP FSSIP FSSP FWAGP FWKHP FWKLP FWKWP FYOEP PWGTP1 PWGTP2 PWGTP3 PWGTP4 PWGTP5 PWGTP6 PWGTP7 PWGTP8 PWGTP9 PWGTP10 PWGTP11 PWGTP12 PWGTP13 PWGTP14 PWGTP15 PWGTP16 PWGTP17 PWGTP18 PWGTP19 PWGTP20 PWGTP21 PWGTP22 PWGTP23 PWGTP24 PWGTP25 PWGTP26 PWGTP27 PWGTP28 PWGTP29 PWGTP30 PWGTP31 PWGTP32 PWGTP33 PWGTP34 PWGTP35 PWGTP36 PWGTP37 PWGTP38 PWGTP39 PWGTP40 PWGTP41 PWGTP42 PWGTP43 PWGTP44 PWGTP45 PWGTP46 PWGTP47 PWGTP48 PWGTP49 PWGTP50 PWGTP51 PWGTP52 PWGTP53 PWGTP54 PWGTP55 PWGTP56 PWGTP57 PWGTP58 PWGTP59 PWGTP60 PWGTP61 PWGTP62 PWGTP63 PWGTP64 PWGTP65 PWGTP66 PWGTP67 PWGTP68 PWGTP69 PWGTP70 PWGTP71 PWGTP72 PWGTP73 PWGTP74 PWGTP75 PWGTP76 PWGTP77 PWGTP78 PWGTP79 PWGTP80
0 2165691 2012000002680 P 1 -9 07506 06 1010207 20 64 1 NaN NaN 2 2 2 2 2 2 NaN NaN 2 NaN NaN 2 NaN NaN 1 2 2 2 2 2 2 0 10 NaN 10 2 5 NaN NaN NaN NaN NaN NaN 1 5 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 3 5 2 2 3 0 0 0 0 1 NaN 21 0 2 0 0 59000 24 1 1 NaN NaN 3 -9 995 -9 999 NaN 2 NaN NaN 1 1 1 7870 84 43 NaN NaN NaN NaN NaN NaN 6 611M1 1 NaN 0 N.A. N.A. 5860 4 59000 59000 -9 36 500 -9 7500 -9 6 1 2 4 1 -9 1 -9 1 0 0 0 0 1 0 1 0 NaN NaN N.A.// N.A.// 439061 NaN 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 NaN 0 NaN 0 NaN 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 21 19 20 6 22 23 31 29 7 6 39 21 6 29 30 22 20 7 22 21 18 17 26 44 18 19 7 5 35 33 7 16 32 7 5 22 16 34 20 14 17 16 22 33 18 17 6 6 41 41 7 17 29 6 6 21 19 30 19 17 18 24 25 6 24 24 32 45 5 7 40 21 6 33 36 18 24 7 16 16
1 2167411 2012000009189 P 1 -9 07506 06 1010207 16 52 4 -9 1995 NaN 2 2 1 2 2 NaN NaN 2 3 NaN 2 NaN NaN 1 2 2 2 2 2 2 0 NaN NaN NaN 1 1 2 2 1 2 -9 1992 1 5 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 3 5 3 3 3 10000 0 0 0 1 NaN 16 0 1 0 0 0 NaN 3 NaN -9 1989 4 -9 999 -9 999 5 1 NaN NaN 6 1 1 NaN NaN NaN -9 708 NaN NaN NaN NaN 1 NaN 2 NaN 0 NaN NaN NaN NaN 0 10000 -9 207 43 NaN NaN NaN NaN 1 2 3 6 -9 43 -9 5 0 1 0 0 1 0 0 0 NaN NaN NaN NaN NaN NaN 4 0 0 0 0 0 1 0 0 1 1 0 0 1 0 1 0 0 0 0 0 0 NaN 0 NaN 0 NaN 0 0 0 1 0 1 0 0 0 0 0 0 1 1 1 1 1 0 0 0 0 1 0 1 1 0 0 0 0 1 0 0 0 1 0 1 1 1 0 1 0 0 19 11 23 20 7 16 11 7 20 4 21 14 16 27 11 20 19 15 18 26 13 33 4 4 50 16 12 40 25 37 19 17 10 3 12 3 11 14 5 5 16 4 28 24 6 19 14 5 17 3 17 15 12 27 13 33 15 19 47 18 22 28 6 5 28 12 12 25 21 15 12 12 15 5 14 7 15 13 7 4
2 2167412 2012000009189 P 2 -9 07506 06 1010207 13 45 4 -9 1998 3 2 2 1 2 2 NaN NaN 2 3 2 2 NaN NaN 1 2 2 2 2 2 2 0 NaN NaN NaN 1 1 2 2 1 2 -9 1992 1 5 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 3 5 3 3 3 0 0 1 0 1 NaN 16 0 2 0 0 0 NaN 2 NaN -9 1992 4 -9 999 -9 999 6 1 NaN NaN 6 1 1 8370 NaN NaN -9 708 NaN NaN NaN NaN 1 6241 2 NaN 0 N.A. N.A. 4610 2 0 0 -9 207 43 NaN NaN NaN NaN 1 2 2 6 -9 43 -9 5 0 1 0 0 1 0 0 0 NaN NaN N.A.// N.A.// 399021 NaN 4 0 0 1 0 1 1 0 0 1 1 0 0 1 1 1 1 0 0 0 0 0 NaN 0 NaN 0 NaN 0 0 0 1 1 1 0 0 0 0 0 0 1 1 1 1 1 0 0 0 0 1 1 1 1 0 0 0 0 1 0 0 0 1 0 1 1 1 0 1 0 0 11 6 25 18 4 15 16 5 12 5 14 13 20 25 9 19 13 16 19 23 12 19 4 4 21 12 12 20 16 21 14 14 11 4 15 3 11 17 4 3 13 5 19 21 4 12 14 4 11 3 19 13 17 25 12 16 12 15 19 27 16 24 5 4 24 12 11 19 13 24 11 16 14 3 15 3 15 12 3 4
3 2167413 2012000009189 P 3 -9 07506 06 1010207 14 10 1 NaN NaN NaN 2 2 2 NaN 2 NaN NaN 2 NaN NaN NaN NaN NaN 2 2 2 1 2 2 2 NaN NaN NaN NaN 2 5 NaN NaN NaN NaN NaN NaN 1 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 2 NaN 1 NaN 7 NaN 1 NaN NaN NaN NaN NaN NaN NaN NaN 4 -9 999 -9 999 NaN 2 NaN 4 NaN 1 1 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 1 4 1 NaN NaN NaN NaN NaN NaN -9 6 43 NaN NaN NaN NaN 2 1 4 6 -9 43 -9 5 0 1 0 0 1 0 0 1 NaN NaN NaN NaN NaN NaN 1 0 0 0 0 0 1 1 1 0 1 0 0 1 0 0 0 0 0 0 0 0 NaN 0 0 0 NaN 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 18 4 24 25 5 12 14 6 14 4 10 12 20 28 16 23 18 18 22 23 18 23 4 3 23 14 15 25 12 19 14 19 13 3 16 4 16 17 4 5 11 5 21 23 6 23 13 4 15 4 19 16 13 26 11 21 13 18 22 23 12 26 5 4 23 14 13 21 15 22 15 13 16 5 12 6 12 12 3 3
4 2167414 2012000009189 P 4 -9 07506 06 1010207 15 8 1 NaN NaN NaN 2 2 2 NaN 2 NaN NaN 2 NaN NaN NaN NaN NaN 2 2 2 1 2 2 2 NaN NaN NaN NaN 2 5 NaN NaN NaN NaN NaN NaN 1 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 2 NaN 2 5 6 NaN 1 NaN NaN NaN NaN NaN NaN NaN NaN 4 -9 999 -9 999 NaN 2 NaN 4 NaN 1 1 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 1 4 1 NaN NaN NaN NaN NaN NaN -9 6 43 NaN NaN NaN NaN 2 1 1 6 -9 43 -9 5 0 1 0 0 1 0 0 1 NaN NaN NaN NaN NaN NaN 1 0 0 0 0 0 1 1 1 0 1 0 0 1 0 0 0 0 0 0 1 1 NaN 1 0 1 NaN 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 1 0 1 0 0 0 0 0 0 0 0 0 18 4 25 24 5 11 13 6 14 4 11 11 20 28 15 23 18 18 22 23 18 23 4 4 23 14 16 25 12 19 15 19 13 4 16 3 16 17 4 5 12 7 21 23 5 23 13 5 16 3 20 16 13 26 12 22 13 17 22 22 13 27 5 3 23 14 13 20 14 22 14 13 17 5 13 6 12 13 4 3

5 rows × 291 columns

Download PUMS for household records for a PUMA


In [7]:
h_pums = c.download_household_pums("06", puma)
h_pums.head(5)


Out[7]:
Unnamed: 0 serialno RT DIVISION PUMA00 PUMA10 REGION ST ADJHSG ADJINC WGTP NP TYPE ACR AGS BATH BDSP BLD BUS CONP ELEP FS FULP GASP HFL INSP MHP MRGI MRGP MRGT MRGX REFR RMSP RNTM RNTP RWAT SINK SMP STOV TEL TEN TOIL VACS VALP VEH WATP YBL FES FINCP FPARC GRNTP GRPIP HHL HHT HINCP HUGCL HUPAC HUPAOC HUPARC KIT LNGI MULTG MV NOC NPF NPP NR NRC OCPIP PARTNER PLM PSF R18 R60 R65 RESMODE SMOCP SMX SRNT SVAL TAXP WIF WKEXREL WORKSTAT FACRP FAGSP FBATHP FBDSP FBLDP FBUSP FCONP FELEP FFSP FFULP FGASP FHFLP FINSP FKITP FMHP FMRGIP FMRGP FMRGTP FMRGXP FMVP FPLMP FREFRP FRMSP FRNTMP FRNTP FRWATP FSINKP FSMP FSMXHP FSMXSP FSTOVP FTAXP FTELP FTENP FTOILP FVACSP FVALP FVEHP FWATP FYBLP WGTP1 WGTP2 WGTP3 WGTP4 WGTP5 WGTP6 WGTP7 WGTP8 WGTP9 WGTP10 WGTP11 WGTP12 WGTP13 WGTP14 WGTP15 WGTP16 WGTP17 WGTP18 WGTP19 WGTP20 WGTP21 WGTP22 WGTP23 WGTP24 WGTP25 WGTP26 WGTP27 WGTP28 WGTP29 WGTP30 WGTP31 WGTP32 WGTP33 WGTP34 WGTP35 WGTP36 WGTP37 WGTP38 WGTP39 WGTP40 WGTP41 WGTP42 WGTP43 WGTP44 WGTP45 WGTP46 WGTP47 WGTP48 WGTP49 WGTP50 WGTP51 WGTP52 WGTP53 WGTP54 WGTP55 WGTP56 WGTP57 WGTP58 WGTP59 WGTP60 WGTP61 WGTP62 WGTP63 WGTP64 WGTP65 WGTP66 WGTP67 WGTP68 WGTP69 WGTP70 WGTP71 WGTP72 WGTP73 WGTP74 WGTP75 WGTP76 WGTP77 WGTP78 WGTP79 WGTP80
0 940390 2012000002680 H 9 -9 07506 4 06 1000000 1010207 21 1 1 1 NaN 1 2 3 2 0 60 2 2 4 9 200 NaN 2 350 2 1 1 5 NaN NaN 1 1 NaN 1 1 1 1 NaN 500000 1 430 1 NaN NaN NaN NaN NaN 1 6 59000 0 4 4 4 1 1 1 6 0 NaN 0 0 0 13 0 1 0 0 1 0 1 634 3 0 1 32 NaN NaN NaN 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 21 19 21 7 22 23 31 29 6 5 39 21 6 29 30 22 20 6 22 21 17 17 26 44 18 20 7 5 35 33 8 17 32 7 5 23 16 35 20 15 17 16 22 34 18 17 6 6 41 41 6 17 30 6 6 21 20 30 19 17 18 25 25 6 24 24 32 45 5 7 39 21 6 33 36 18 24 7 17 16
1 941064 2012000009189 H 9 -9 07506 4 06 1000000 1010207 15 4 1 NaN NaN 1 5 4 NaN 0 50 2 2 50 1 660 NaN 2 490 2 1 1 7 NaN NaN 1 1 630 1 1 1 1 NaN 40000 2 2000 1 4 10000 2 NaN NaN 4 1 10000 0 2 2 2 1 2 1 5 2 4 0 0 2 101 0 1 0 1 0 0 1 1534 2 0 0 23 0 9 9 0 0 0 1 1 0 0 0 0 1 0 1 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 19 11 23 20 7 16 11 7 20 5 21 14 15 27 11 20 18 15 18 26 13 33 4 4 50 16 13 40 25 37 19 17 10 4 13 3 11 14 6 4 16 4 28 24 6 19 15 5 18 3 17 15 12 27 13 33 14 19 47 18 22 28 5 6 28 13 12 26 21 15 12 12 15 5 13 7 15 13 7 5
2 941824 2012000016466 H 9 -9 07506 4 06 1000000 1010207 15 3 1 1 NaN 1 2 2 2 0 10 2 2 1 1 NaN NaN NaN NaN NaN NaN 1 4 2 2000 1 1 NaN 1 1 3 1 NaN NaN 1 1 2 7 30000 2 2010 80 1 3 30000 0 2 2 2 1 1 1 2 2 3 0 0 2 NaN 0 1 0 1 0 0 1 NaN NaN 1 0 NaN 1 13 13 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 5 32 14 5 21 21 12 16 6 15 19 20 18 5 13 19 23 25 11 23 21 5 22 24 5 8 12 17 35 24 15 17 10 14 13 16 5 5 18 3 6 27 21 5 25 28 14 10 7 13 15 17 21 4 14 14 22 22 15 31 26 5 17 34 7 4 17 20 24 12 12 14 14 26 18 13 4 5 16
3 941918 2012000017340 H 9 -9 07506 4 06 1000000 1010207 10 4 1 1 NaN 1 3 3 2 0 100 2 1000 30 3 500 NaN 2 3000 2 1 1 4 NaN NaN 1 1 NaN 1 1 1 1 NaN 500000 1 1200 7 5 60000 4 NaN NaN 4 2 60000 0 4 4 4 1 1 1 4 0 4 0 0 0 79 0 1 1 0 1 0 1 3938 3 0 1 65 2 12 11 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 12 8 3 8 4 6 8 12 17 7 20 11 11 18 14 4 30 23 4 20 10 10 19 9 15 6 12 10 3 12 4 11 8 4 9 18 5 3 18 4 12 10 4 13 3 12 13 10 28 13 20 16 11 17 11 3 18 15 3 13 9 8 14 12 17 10 10 9 5 8 3 13 11 2 9 19 2 3 13 3
4 942803 2012000025664 H 9 -9 07506 4 06 1000000 1010207 71 5 1 1 NaN 1 3 3 2 0 50 2 2 3 3 200 NaN 2 680 2 1 1 6 NaN NaN 1 1 NaN 1 1 1 1 NaN 500000 2 900 4 7 73500 4 NaN NaN 1 3 73500 0 4 4 4 1 1 2 7 0 5 0 0 0 16 0 1 0 0 1 1 2 989 3 0 1 32 3 13 13 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 1 1 0 0 0 0 0 0 0 0 0 1 1 1 0 1 0 0 0 0 1 0 0 1 33 23 78 66 19 99 88 97 68 29 80 72 50 74 36 57 82 101 77 75 69 93 23 131 105 27 25 83 69 93 65 57 92 74 108 89 128 38 17 55 102 103 44 61 109 29 31 69 66 94 73 66 77 62 104 82 78 38 30 87 37 21 85 63 25 66 93 80 55 29 90 74 86 63 19 70 50 100 115 70

5 rows × 204 columns

Now the job is to categorize acs and pums into the same categories - we start with the household acs data


In [8]:
h_acs_cat = cat.categorize(h_acs, {
    ("households", "total"): "B11001_001E",
    ("children", "yes"): "B11001_002E",
    ("children", "no"): "B11001_001E - B11001_002E",
    ("income", "lt35"): "B19001_002E + B19001_003E + B19001_004E + "
                        "B19001_005E + B19001_006E + B19001_007E",
    ("income", "gt35-lt100"): "B19001_008E + B19001_009E + "
                        "B19001_010E + B19001_011E + B19001_012E"
                        "+ B19001_013E",
    ("income", "gt100"): "B19001_014E + B19001_015E + B19001_016E"
                        "+ B19001_017E",
    ("cars", "none"): "B08201_002E",
    ("cars", "one"): "B08201_003E",
    ("cars", "two or more"): "B08201_004E + B08201_005E + B08201_006E",
    ("workers", "none"): "B08202_002E",
    ("workers", "one"): "B08202_003E",
    ("workers", "two or more"): "B08202_004E + B08202_005E" 
}, index_cols=['NAME'])
h_acs_cat


Out[8]:
cat_name cars children households income workers
cat_value none one two or more no yes total gt100 gt35-lt100 lt35 none one two or more
NAME
Block Group 1, Census Tract 306, San Francisco County, California 14 86 192 111 183 294 173 73 48 65 89 138
Block Group 2, Census Tract 306, San Francisco County, California 11 66 147 88 138 226 156 20 50 50 68 106
Block Group 3, Census Tract 306, San Francisco County, California 14 84 187 50 237 287 194 40 53 64 87 134

3 rows × 12 columns


In [9]:
assert np.all(cat.sum_accross_category(h_acs_cat) < 2)

And the same for ACS population - the output of the categorization is the MARGINALS for each variable category


In [10]:
p_acs_cat = cat.categorize(p_acs, {
    ("population", "total"): "B01001_001E",
    ("age", "19 and under"): "B01001_003E + B01001_004E + B01001_005E + "
                             "B01001_006E + B01001_007E + B01001_027E + "
                             "B01001_028E + B01001_029E + B01001_030E + "
                             "B01001_031E",
    ("age", "20 to 35"): "B01001_008E + B01001_009E + B01001_010E + "
                         "B01001_011E + B01001_012E + B01001_032E + "
                         "B01001_033E + B01001_034E + B01001_035E + "
                         "B01001_036E",
    ("age", "35 to 60"): "B01001_013E + B01001_014E + B01001_015E + "
                         "B01001_016E + B01001_017E + B01001_037E + "
                         "B01001_038E + B01001_039E + B01001_040E + "
                         "B01001_041E",
    ("age", "above 60"): "B01001_018E + B01001_019E + B01001_020E + "
                         "B01001_021E + B01001_022E + B01001_023E + "
                         "B01001_024E + B01001_025E + B01001_042E + "
                         "B01001_043E + B01001_044E + B01001_045E + "
                         "B01001_046E + B01001_047E + B01001_048E + "
                         "B01001_049E", 
    ("race", "white"):   "B02001_002E",
    ("race", "black"):   "B02001_003E",
    ("race", "asian"):   "B02001_005E",
    ("race", "other"):   "B02001_004E + B02001_006E + B02001_007E + "
                         "B02001_008E",
    ("sex", "male"):     "B01001_002E",
    ("sex", "female"):   "B01001_026E"
}, index_cols=['NAME'])
p_acs_cat


Out[10]:
cat_name age population race sex
cat_value 19 and under 20 to 35 35 to 60 above 60 total asian black other white female male
NAME
Block Group 1, Census Tract 306, San Francisco County, California 129 62 296 168 655 187 11 34 423 334 321
Block Group 2, Census Tract 306, San Francisco County, California 97 34 288 109 528 11 9 60 448 292 236
Block Group 3, Census Tract 306, San Francisco County, California 203 78 411 166 858 218 11 6 623 365 493

3 rows × 11 columns


In [11]:
assert np.all(cat.sum_accross_category(p_acs_cat) < 2)

To get the marginals a series for one geography do this


In [12]:
p_acs_cat.iloc[0].transpose()


Out[12]:
cat_name    cat_value   
age         19 and under    129
            20 to 35         62
            35 to 60        296
            above 60        168
population  total           655
race        asian           187
            black            11
            other            34
            white           423
sex         female          334
            male            321
Name: Block Group 1, Census Tract 306, San Francisco County, California, dtype: int64

Now categorize the PUMS population data into the same categories


In [13]:
def age_cat(r):
    if r.AGEP <= 19: return "19 and under"
    elif r.AGEP <= 35: return "20 to 35"
    elif r.AGEP <= 60: return "35 to 60"
    return "above 60"

def race_cat(r):
    if r.RAC1P == 1: return "white"
    elif r.RAC1P == 2: return "black"
    elif r.RAC1P == 6: return "asian"
    return "other"

def sex_cat(r):
    if r.SEX == 1: return "male"
    return "female"

_, jd_persons = cat.joint_distribution(
    p_pums,
    cat.category_combinations(p_acs_cat.columns),
    {"age": age_cat, "race": race_cat, "sex": sex_cat}
)
jd_persons


Out[13]:
id frequency
age race sex
19 and under asian female 0 37
male 1 44
black female 2 1
male 3 5
other female 4 21
male 5 25
white female 6 42
male 7 35
20 to 35 asian female 8 42
male 9 47
black female 10 6
male 11 6
other female 12 12
male 13 13
white female 14 44
male 15 43
35 to 60 asian female 16 96
male 17 81
black female 18 10
male 19 7
other female 20 22
male 21 17
white female 22 68
male 23 88
above 60 asian female 24 56
male 25 38
black female 26 14
male 27 8
other female 28 7
male 29 5
white female 30 64
male 31 59

32 rows × 2 columns

Do the same for households - the output of this step is the JOINT DISTRIBUTIONS for the cross product of all possible categories


In [14]:
def cars_cat(r):
    if r.VEH == 0: return "none"
    elif r.VEH == 1: return "one"
    return "two or more"

def children_cat(r):
    if r.NOC > 0: return "yes"
    return "no"

def income_cat(r):
    if r.FINCP > 100000: return "gt100"
    elif r.FINCP > 35000: return "gt35-lt100"
    return "lt35"

def workers_cat(r):
    if r.WIF == 3: return "two or more"
    elif r.WIF == 2: return "two or more"
    elif r.WIF == 1: return "one"
    return "none"

_, jd_households = cat.joint_distribution(
    h_pums,
    cat.category_combinations(h_acs_cat.columns),
    {"cars": cars_cat, "children": children_cat, 
     "income": income_cat, "workers": workers_cat}
)
jd_households


Out[14]:
id frequency
cars workers children income
none none no gt100 0 0
gt35-lt100 1 1
lt35 2 37
yes gt100 3 0
gt35-lt100 4 0
lt35 5 0
one no gt100 6 0
gt35-lt100 7 2
lt35 8 2
yes gt100 9 0
gt35-lt100 10 1
lt35 11 0
two or more no gt100 12 2
gt35-lt100 13 5
lt35 14 0
yes gt100 15 0
gt35-lt100 16 1
lt35 17 0
one none no gt100 18 1
gt35-lt100 19 7
lt35 20 81
yes gt100 21 0
gt35-lt100 22 0
lt35 23 0
one no gt100 24 5
gt35-lt100 25 6
lt35 26 2
yes gt100 27 3
gt35-lt100 28 6
lt35 29 8
two or more no gt100 30 8
gt35-lt100 31 10
lt35 32 1
yes gt100 33 6
gt35-lt100 34 7
lt35 35 1
two or more none no gt100 36 2
gt35-lt100 37 8
lt35 38 91
yes gt100 39 0
gt35-lt100 40 0
lt35 41 1
one no gt100 42 5
gt35-lt100 43 8
lt35 44 5
yes gt100 45 6
gt35-lt100 46 6
lt35 47 0
two or more no gt100 48 36
gt35-lt100 49 22
lt35 50 5
yes gt100 51 36
gt35-lt100 52 10
lt35 53 0

54 rows × 2 columns

With marginals (aggregate, from ACS) and joint distribution (disaggregate, from PUMS) we're ready for some synthesis


In [16]:
"TBD"


Out[16]:
'TBD'

In [ ]: