├── cuyahoga_2012_votes.xls ├── cuyahoga_2016_primary.xls ├── requirements.txt ├── .gitignore ├── README.md ├── censusreporter_api.py ├── Basic Census Reporter API with Pandas.ipynb ├── 538_race_income_gap.ipynb ├── Cuyahoga Voting.ipynb └── Big race changes.ipynb /cuyahoga_2012_votes.xls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/censusreporter/notebooks/HEAD/cuyahoga_2012_votes.xls -------------------------------------------------------------------------------- /cuyahoga_2016_primary.xls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/censusreporter/notebooks/HEAD/cuyahoga_2016_primary.xls -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | pandas==0.18.1 2 | jsonschema==2.4.0 3 | psycopg2==2.6 4 | SQLAlchemy==1.0.4 5 | bokeh==0.11.1 6 | matplotlib==1.5.1 7 | jupyter==1.0.0 8 | jupyter-client==5.1.0 9 | jupyter-console==5.1.0 10 | jupyter-core==4.3.0 11 | six==1.10.0 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | 5 | # C extensions 6 | *.so 7 | 8 | # Distribution / packaging 9 | .Python 10 | env/ 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | *.egg-info/ 23 | .installed.cfg 24 | *.egg 25 | 26 | # PyInstaller 27 | # Usually these files are written by a python script from a template 28 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 29 | *.manifest 30 | *.spec 31 | 32 | # Installer logs 33 | pip-log.txt 34 | pip-delete-this-directory.txt 35 | 36 | # Unit test / coverage reports 37 | htmlcov/ 38 | .tox/ 39 | .coverage 40 | .coverage.* 41 | .cache 42 | nosetests.xml 43 | coverage.xml 44 | *,cover 45 | 46 | # Translations 47 | *.mo 48 | *.pot 49 | 50 | # Django stuff: 51 | *.log 52 | 53 | # Sphinx documentation 54 | docs/_build/ 55 | 56 | # PyBuilder 57 | target/ 58 | 59 | # IPython 60 | .ipynb_checkpoints 61 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # notebooks 2 | 3 | With the recent announcement that [Github would directly render Jupyter notebooks](http://blog.jupyter.org/2015/05/07/rendering-notebooks-on-github/), 4 | it seems interesting to try an experiment. 5 | 6 | Census Reporter invites you to make pull requests for notebooks demonstrating methods for analyzing Census data. 7 | What that looks like remains to be seen! Join in if you want to help figure it out. 8 | 9 | # index 10 | 11 | * [Basic Census Reporter API with Pandas](Basic Census Reporter API with Pandas.ipynb) 12 | * [Looking at Black/White income gap in cities / FiveThirtyEight article](538_race_income_gap.ipynb) 13 | 14 | 15 |
16 | Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. 17 | -------------------------------------------------------------------------------- /censusreporter_api.py: -------------------------------------------------------------------------------- 1 | # set up some utility methods. If we ever make a python API wrapper, these belong there. 2 | import requests 3 | import pandas as pd 4 | from six import string_types 5 | 6 | API_URL="http://api.censusreporter.org/1.0/data/show/{release}?table_ids={table_ids}&geo_ids={geoids}" 7 | SEARCH_API_URL="http://api.censusreporter.org/2.1/full-text/search?type=profile&q={query}" 8 | 9 | def _clean_list_arg(arg,default): 10 | if arg is None: 11 | arg = default 12 | if isinstance(arg,string_types): 13 | arg = [arg] 14 | return arg 15 | 16 | def json_data(tables=None, geoids=None, release='latest'): 17 | """Make a basic API request for data for a given table, geoid, and/or release. 18 | 19 | tables -- An ACS table ID as a string, or a list of such IDs. Default: 'B01001' 20 | geoids -- A Census geoID as a string, or a list of such IDs. Default: '040|01000US' ('all states in the US') 21 | release -- The ACS release from which to retrieve data. Should be one of: 22 | latest - (default) the ACS release which has data for all of the requested geographies 23 | acs2013_1yr - the 2013 1-year ACS data. Only includes geographies with population >65,000 24 | acs2013_3yr - the 2011-13 3-year ACS data. Only includes geographies with population >20,000 25 | acs2013_5yr - the 2009-13 5-year ACS data. Includes all geographies covered in the ACS. 26 | """ 27 | geoids = _clean_list_arg(geoids,'040|01000US') 28 | tables = _clean_list_arg(tables,'B01001') 29 | 30 | url = API_URL.format(table_ids=','.join(tables).upper(), 31 | geoids=','.join(geoids), 32 | release=release) 33 | 34 | response = requests.get(url) 35 | return response.json() 36 | 37 | def _prep_data_for_pandas(json_data,include_moe=False): 38 | """Given a dict of dicts as they come from a Census Reporter API call, set it up to be amenable to pandas.DataFrame.from_dict""" 39 | result = {} 40 | for geoid, tables in json_data['data'].items(): 41 | flat = {} 42 | for table,values in tables.items(): 43 | for kind, columns in values.items(): 44 | if kind == 'estimate': 45 | flat.update(columns) 46 | elif kind == 'error' and include_moe: 47 | renamed = dict((k+"_moe",v) for k,v in columns.items()) 48 | flat.update(renamed) 49 | result[geoid] = flat 50 | return result 51 | 52 | def _prep_headers_for_pandas(json_data,separator=":", level=None, include_moe=False): 53 | headers = {} 54 | for table in json_data['tables']: 55 | stack = [ None ] * 10 # pretty sure no columns are nested deeper than this. 56 | for column in sorted(json_data['tables'][table]['columns']): 57 | col_md = json_data['tables'][table]['columns'][column] 58 | indent = col_md['indent'] 59 | name = col_md['name'].strip(separator) 60 | stack[indent] = name 61 | parts = [] 62 | if indent > 0: 63 | for i in range(1,indent+1): 64 | if stack[i] is not None: 65 | parts.append(stack[i].strip(separator)) 66 | name = separator.join(parts) 67 | if level is None or indent <= level: 68 | headers[column] = name 69 | if include_moe: 70 | moe_col = '{}_moe'.format(column) 71 | headers[moe_col] = "{} (error)".format(name) 72 | return headers 73 | 74 | def search_places(q,sumlevel=None,sumlevels=None): 75 | url = SEARCH_API_URL.format(query=q) 76 | resp = requests.get(url) 77 | j = resp.json() 78 | if sumlevel is not None: 79 | sumlevels = [ sumlevel ] 80 | if sumlevels is not None: 81 | sumlevels = map(str,sumlevels) 82 | return map(lambda x: x['sumlevel'] in sumlevels, j['results']) 83 | else: 84 | return j['results'] 85 | 86 | def get_dataframe(tables=None, geoids=None, release='latest',level=None,place_names=True,column_names=True, include_moe=False): 87 | """Return a pandas DataFrame object for the given tables and geoids. 88 | 89 | Keyword arguments (all optional): 90 | tables -- An ACS table ID as a string, or a list of such IDs. Default: 'B01001' 91 | geoids -- A Census geoID as a string, or a list of such IDs. Default: '040|01000US' ('all states in the US') 92 | release -- The ACS release from which to retrieve data. Should be one of: 93 | latest - (default) the ACS release which has data for all of the requested geographies 94 | acs2013_1yr - the 2013 1-year ACS data. Only includes geographies with population >65,000 95 | acs2013_3yr - the 2011-13 3-year ACS data. Only includes geographies with population >20,000 96 | acs2013_5yr - the 2009-13 5-year ACS data. Includes all geographies covered in the ACS. 97 | level -- if provided, should be an integer representing the maximum "indent level" of columns to be returned. Generally, '0' is the total column. 98 | place_names -- specify False to omit a 'name' column for each geography row 99 | column_names -- specify False to preserve the coded column names instead of using verbal labels 100 | include_moe -- specify True to include error columns. Defaults to false. 101 | 102 | """ 103 | response = json_data(tables, geoids, release) 104 | if 'error' in response: 105 | raise Exception(response['error']) 106 | df = pd.DataFrame.from_dict(_prep_data_for_pandas(response, include_moe=include_moe),orient='index') 107 | df = df.reindex_axis(sorted(df.columns), axis=1) 108 | if column_names or level is not None: 109 | headers = _prep_headers_for_pandas(response, level=level, include_moe=include_moe) 110 | if level is not None: 111 | df = df.select(lambda x: x in headers,axis=1) 112 | if column_names: 113 | df = df.rename(columns=headers) 114 | if place_names: 115 | name_frame = pd.DataFrame.from_dict(response['geography'],orient='index') 116 | df.insert(0, 'name', name_frame.name) 117 | return df 118 | -------------------------------------------------------------------------------- /Basic Census Reporter API with Pandas.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Basic Census Reporter API with Pandas" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 1, 13 | "metadata": { 14 | "collapsed": true 15 | }, 16 | "outputs": [], 17 | "source": [ 18 | "from censusreporter_api import * # a few convenience methods elsewhere in this repo. Not a full pypi project at the moment" 19 | ] 20 | }, 21 | { 22 | "cell_type": "markdown", 23 | "metadata": {}, 24 | "source": [ 25 | "# Top 5 States by Total Population" 26 | ] 27 | }, 28 | { 29 | "cell_type": "code", 30 | "execution_count": 2, 31 | "metadata": {}, 32 | "outputs": [ 33 | { 34 | "data": { 35 | "text/html": [ 36 | "
\n", 37 | "\n", 38 | " \n", 39 | " \n", 40 | " \n", 41 | " \n", 42 | " \n", 43 | " \n", 44 | " \n", 45 | " \n", 46 | " \n", 47 | " \n", 48 | " \n", 49 | " \n", 50 | " \n", 51 | " \n", 52 | " \n", 53 | " \n", 54 | " \n", 55 | " \n", 56 | " \n", 57 | " \n", 58 | " \n", 59 | " \n", 60 | " \n", 61 | " \n", 62 | " \n", 63 | " \n", 64 | " \n", 65 | " \n", 66 | " \n", 67 | " \n", 68 | " \n", 69 | " \n", 70 | " \n", 71 | " \n", 72 | " \n", 73 | " \n", 74 | " \n", 75 | " \n", 76 | " \n", 77 | " \n", 78 | " \n", 79 | " \n", 80 | " \n", 81 | " \n", 82 | " \n", 83 | " \n", 84 | "
nameTotalMaleFemale
04000US06California39144818.019440558.019704260.0
04000US48Texas27469114.013625413.013843701.0
04000US12Florida20271272.09891238.010380034.0
04000US36New York19795791.09616592.010179199.0
04000US17Illinois12859995.06310435.06549560.0
\n", 85 | "
" 86 | ], 87 | "text/plain": [ 88 | " name Total Male Female\n", 89 | "04000US06 California 39144818.0 19440558.0 19704260.0\n", 90 | "04000US48 Texas 27469114.0 13625413.0 13843701.0\n", 91 | "04000US12 Florida 20271272.0 9891238.0 10380034.0\n", 92 | "04000US36 New York 19795791.0 9616592.0 10179199.0\n", 93 | "04000US17 Illinois 12859995.0 6310435.0 6549560.0" 94 | ] 95 | }, 96 | "execution_count": 2, 97 | "metadata": {}, 98 | "output_type": "execute_result" 99 | } 100 | ], 101 | "source": [ 102 | "df = get_dataframe(tables='B01001',geoids='040|01000US',column_names=True,level=1)\n", 103 | "df.sort_values('Total', ascending=False).head(5)" 104 | ] 105 | }, 106 | { 107 | "cell_type": "markdown", 108 | "metadata": {}, 109 | "source": [ 110 | "## Top 5 States in Midwest Region by % Female Population" 111 | ] 112 | }, 113 | { 114 | "cell_type": "code", 115 | "execution_count": 3, 116 | "metadata": {}, 117 | "outputs": [ 118 | { 119 | "data": { 120 | "text/html": [ 121 | "
\n", 122 | "\n", 123 | " \n", 124 | " \n", 125 | " \n", 126 | " \n", 127 | " \n", 128 | " \n", 129 | " \n", 130 | " \n", 131 | " \n", 132 | " \n", 133 | " \n", 134 | " \n", 135 | " \n", 136 | " \n", 137 | " \n", 138 | " \n", 139 | " \n", 140 | " \n", 141 | " \n", 142 | " \n", 143 | " \n", 144 | " \n", 145 | " \n", 146 | " \n", 147 | " \n", 148 | " \n", 149 | " \n", 150 | " \n", 151 | " \n", 152 | " \n", 153 | " \n", 154 | " \n", 155 | " \n", 156 | " \n", 157 | " \n", 158 | " \n", 159 | " \n", 160 | " \n", 161 | " \n", 162 | " \n", 163 | " \n", 164 | " \n", 165 | " \n", 166 | " \n", 167 | " \n", 168 | " \n", 169 | " \n", 170 | " \n", 171 | " \n", 172 | " \n", 173 | " \n", 174 | " \n", 175 | "
nameTotalMaleFemalepct_female
04000US47Tennessee6600299.03214689.03385610.00.512948
04000US42Pennsylvania12802503.06262246.06540257.00.510858
04000US39Ohio11613423.05683951.05929472.00.510571
04000US29Missouri6083672.02983645.03100027.00.509565
04000US17Illinois12859995.06310435.06549560.00.509297
\n", 176 | "
" 177 | ], 178 | "text/plain": [ 179 | " name Total Male Female pct_female\n", 180 | "04000US47 Tennessee 6600299.0 3214689.0 3385610.0 0.512948\n", 181 | "04000US42 Pennsylvania 12802503.0 6262246.0 6540257.0 0.510858\n", 182 | "04000US39 Ohio 11613423.0 5683951.0 5929472.0 0.510571\n", 183 | "04000US29 Missouri 6083672.0 2983645.0 3100027.0 0.509565\n", 184 | "04000US17 Illinois 12859995.0 6310435.0 6549560.0 0.509297" 185 | ] 186 | }, 187 | "execution_count": 3, 188 | "metadata": {}, 189 | "output_type": "execute_result" 190 | } 191 | ], 192 | "source": [ 193 | "df = get_dataframe(tables='B01001',geoids='040|02000US2',column_names=True,level=1)\n", 194 | "df['pct_female'] = df['Female'] / df['Total']\n", 195 | "df.sort_values('pct_female',ascending=False).head(5)" 196 | ] 197 | }, 198 | { 199 | "cell_type": "markdown", 200 | "metadata": {}, 201 | "source": [ 202 | "## Top 5 Tennessee Counties by % Male Population" 203 | ] 204 | }, 205 | { 206 | "cell_type": "code", 207 | "execution_count": 4, 208 | "metadata": {}, 209 | "outputs": [ 210 | { 211 | "data": { 212 | "text/html": [ 213 | "
\n", 214 | "\n", 215 | " \n", 216 | " \n", 217 | " \n", 218 | " \n", 219 | " \n", 220 | " \n", 221 | " \n", 222 | " \n", 223 | " \n", 224 | " \n", 225 | " \n", 226 | " \n", 227 | " \n", 228 | " \n", 229 | " \n", 230 | " \n", 231 | " \n", 232 | " \n", 233 | " \n", 234 | " \n", 235 | " \n", 236 | " \n", 237 | " \n", 238 | " \n", 239 | " \n", 240 | " \n", 241 | " \n", 242 | " \n", 243 | " \n", 244 | " \n", 245 | " \n", 246 | " \n", 247 | " \n", 248 | " \n", 249 | " \n", 250 | " \n", 251 | " \n", 252 | " \n", 253 | " \n", 254 | " \n", 255 | " \n", 256 | " \n", 257 | " \n", 258 | " \n", 259 | " \n", 260 | " \n", 261 | " \n", 262 | " \n", 263 | " \n", 264 | " \n", 265 | " \n", 266 | " \n", 267 | "
nameTotalMaleFemalepct_male
05000US47095Lake County, TN7687.04937.02750.00.642253
05000US47007Bledsoe County, TN13686.07677.06009.00.560938
05000US47129Morgan County, TN21794.012150.09644.00.557493
05000US47181Wayne County, TN16897.09295.07602.00.550098
05000US47069Hardeman County, TN26253.014297.011956.00.544585
\n", 268 | "
" 269 | ], 270 | "text/plain": [ 271 | " name Total Male Female pct_male\n", 272 | "05000US47095 Lake County, TN 7687.0 4937.0 2750.0 0.642253\n", 273 | "05000US47007 Bledsoe County, TN 13686.0 7677.0 6009.0 0.560938\n", 274 | "05000US47129 Morgan County, TN 21794.0 12150.0 9644.0 0.557493\n", 275 | "05000US47181 Wayne County, TN 16897.0 9295.0 7602.0 0.550098\n", 276 | "05000US47069 Hardeman County, TN 26253.0 14297.0 11956.0 0.544585" 277 | ] 278 | }, 279 | "execution_count": 4, 280 | "metadata": {}, 281 | "output_type": "execute_result" 282 | } 283 | ], 284 | "source": [ 285 | "df = get_dataframe(tables='B01001',geoids='050|04000US47',column_names=True,level=1)\n", 286 | "df['pct_male'] = df['Male'] / df['Total']\n", 287 | "df.sort_values('pct_male',ascending=False).head(5)" 288 | ] 289 | } 290 | ], 291 | "metadata": { 292 | "kernelspec": { 293 | "display_name": "Python 3", 294 | "language": "python", 295 | "name": "python3" 296 | }, 297 | "language_info": { 298 | "codemirror_mode": { 299 | "name": "ipython", 300 | "version": 3 301 | }, 302 | "file_extension": ".py", 303 | "mimetype": "text/x-python", 304 | "name": "python", 305 | "nbconvert_exporter": "python", 306 | "pygments_lexer": "ipython3", 307 | "version": "3.4.3" 308 | } 309 | }, 310 | "nbformat": 4, 311 | "nbformat_minor": 1 312 | } 313 | -------------------------------------------------------------------------------- /538_race_income_gap.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Black/White income gap in cities" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "I was intrigued by [a FiveThirtyEight.com story](http://fivethirtyeight.com/datalab/how-baltimores-young-black-men-are-boxed-in/) that included this image:\n", 15 | "\n", 16 | "![this image](https://espnfivethirtyeight.files.wordpress.com/2015/04/casselman-datalab-baltimore-1.png?w=610&h=521)\n", 17 | "\n", 18 | "I wanted to know which were the places towards the bottom right quadrant, where black median income outpaced white so dramatically. I am also always looking for chances to practice Pandas and iPython notebook and see how well our [Census Reporter SQL data](http://censusreporter.tumblr.com/post/73727555158/easier-access-to-acs-data) can be applied to this kind of work, so I made this notebook." 19 | ] 20 | }, 21 | { 22 | "cell_type": "code", 23 | "execution_count": 1, 24 | "metadata": {}, 25 | "outputs": [], 26 | "source": [ 27 | "# basic setup. You'd do this every time you set out to use pandas with Census Reporter's SQL\n", 28 | "import pandas as pd\n", 29 | "from sqlalchemy import create_engine \n", 30 | "# for below to work, you must set the PGPASSWORD env variable or have no-password login enabled\n", 31 | "engine = create_engine('postgresql://census@localhost:5432/census')" 32 | ] 33 | }, 34 | { 35 | "cell_type": "markdown", 36 | "metadata": {}, 37 | "source": [ 38 | "After I published this, [Ben Casselman clarified](https://twitter.com/bencasselman/status/595276073077776385) that they used [B19013H Median Household Income (White alone, not Hispanic)](http://censusreporter.org/tables/B19013H/) and [B19013B Median Household Income (Black alone)](http://censusreporter.org/tables/B19013B/) tables from the ACS2013-3 year release." 39 | ] 40 | }, 41 | { 42 | "cell_type": "code", 43 | "execution_count": 2, 44 | "metadata": {}, 45 | "outputs": [], 46 | "source": [ 47 | "# load in white and black median income for Census places (sumlevel = 160)\n", 48 | "white = pd.read_sql_query(\"select g.geoid, g.name, d.b19013h001 as white \\\n", 49 | " from acs2013_3yr.geoheader g, \\\n", 50 | " acs2013_3yr.b19013h d \\\n", 51 | " where d.geoid = g.geoid \\\n", 52 | " and g.sumlevel = 160\",engine, index_col='geoid')\n", 53 | "black = pd.read_sql_query(\"select g.geoid, d.b19013b001 as black \\\n", 54 | " from acs2013_3yr.geoheader g, \\\n", 55 | " acs2013_3yr.b19013b d \\\n", 56 | " where d.geoid = g.geoid \\\n", 57 | " and g.sumlevel = 160\",engine, index_col='geoid')\n" 58 | ] 59 | }, 60 | { 61 | "cell_type": "code", 62 | "execution_count": 3, 63 | "metadata": {}, 64 | "outputs": [], 65 | "source": [ 66 | "# put the parts together and compute the gap\n", 67 | "df = white.join(black)\n", 68 | "df = df.dropna()\n", 69 | "df['gap'] = df.white - df.black\n", 70 | "df.sort_values(by='gap',ascending=True,inplace=True)\n" 71 | ] 72 | }, 73 | { 74 | "cell_type": "markdown", 75 | "metadata": {}, 76 | "source": [ 77 | "The 538 chart specifies places where blacks make up 10% or more of the population. So, add population of each group. Since the median income above specifies White non-hispanic, we need to use [B03002 Hispanic or Latino Origin by Race](http://censusreporter.org/tables/B03002/)." 78 | ] 79 | }, 80 | { 81 | "cell_type": "code", 82 | "execution_count": 4, 83 | "metadata": {}, 84 | "outputs": [], 85 | "source": [ 86 | "df.rename(columns={'white': 'white_income', 'black': 'black_income'}, inplace=True)\n", 87 | "population = pd.read_sql_query(\"select geoid, b03002001 as total_pop, b03002003 as white_pop, \\\n", 88 | " b03002004+b03002014 as black_pop from acs2013_3yr.b03002 \\\n", 89 | " where geoid like '16000US%%'\",\n", 90 | " engine, index_col='geoid')\n", 91 | "df = df.join(population)" 92 | ] 93 | }, 94 | { 95 | "cell_type": "code", 96 | "execution_count": 5, 97 | "metadata": { 98 | "collapsed": true 99 | }, 100 | "outputs": [], 101 | "source": [ 102 | "df.dropna(inplace=True)\n", 103 | "df['black_pop_pct'] = df.black_pop / df.total_pop\n", 104 | "# I'm running out of creative names for my variables\n", 105 | "df2 = df[(df.black_pop_pct >=.1) & (df.gap < 0)]\n" 106 | ] 107 | }, 108 | { 109 | "cell_type": "code", 110 | "execution_count": 6, 111 | "metadata": {}, 112 | "outputs": [ 113 | { 114 | "data": { 115 | "text/html": [ 116 | "
\n", 117 | "\n", 118 | " \n", 119 | " \n", 120 | " \n", 121 | " \n", 122 | " \n", 123 | " \n", 124 | " \n", 125 | " \n", 126 | " \n", 127 | " \n", 128 | " \n", 129 | " \n", 130 | " \n", 131 | " \n", 132 | " \n", 133 | " \n", 134 | " \n", 135 | " \n", 136 | " \n", 137 | " \n", 138 | " \n", 139 | " \n", 140 | " \n", 141 | " \n", 142 | " \n", 143 | " \n", 144 | " \n", 145 | " \n", 146 | " \n", 147 | " \n", 148 | " \n", 149 | " \n", 150 | " \n", 151 | " \n", 152 | " \n", 153 | " \n", 154 | " \n", 155 | " \n", 156 | " \n", 157 | " \n", 158 | " \n", 159 | " \n", 160 | " \n", 161 | " \n", 162 | " \n", 163 | " \n", 164 | " \n", 165 | " \n", 166 | " \n", 167 | " \n", 168 | " \n", 169 | " \n", 170 | " \n", 171 | " \n", 172 | " \n", 173 | " \n", 174 | " \n", 175 | " \n", 176 | " \n", 177 | " \n", 178 | " \n", 179 | " \n", 180 | " \n", 181 | " \n", 182 | " \n", 183 | " \n", 184 | " \n", 185 | " \n", 186 | " \n", 187 | " \n", 188 | " \n", 189 | " \n", 190 | " \n", 191 | " \n", 192 | " \n", 193 | " \n", 194 | " \n", 195 | " \n", 196 | " \n", 197 | " \n", 198 | " \n", 199 | " \n", 200 | " \n", 201 | " \n", 202 | " \n", 203 | " \n", 204 | " \n", 205 | " \n", 206 | " \n", 207 | " \n", 208 | " \n", 209 | " \n", 210 | " \n", 211 | " \n", 212 | " \n", 213 | " \n", 214 | " \n", 215 | " \n", 216 | " \n", 217 | " \n", 218 | " \n", 219 | " \n", 220 | " \n", 221 | " \n", 222 | " \n", 223 | " \n", 224 | " \n", 225 | " \n", 226 | " \n", 227 | " \n", 228 | " \n", 229 | " \n", 230 | " \n", 231 | " \n", 232 | " \n", 233 | " \n", 234 | " \n", 235 | " \n", 236 | " \n", 237 | " \n", 238 | " \n", 239 | " \n", 240 | " \n", 241 | " \n", 242 | " \n", 243 | " \n", 244 | " \n", 245 | " \n", 246 | " \n", 247 | " \n", 248 | " \n", 249 | " \n", 250 | " \n", 251 | " \n", 252 | " \n", 253 | " \n", 254 | "
namewhite_incomeblack_incomegaptotal_popwhite_popblack_popblack_pop_pct
geoid
16000US0672520Soledad city, California60441.0147632.0-87191.026251.03391.03312.00.126167
16000US3676089Uniondale CDP, New York36991.098148.0-61157.025905.02416.011635.00.449141
16000US3676705Valley Stream village, New York78736.0122880.0-44144.037618.013727.06763.00.179781
16000US3624273Elmont CDP, New York63913.096223.0-32310.039761.06260.019265.00.484520
16000US0611530Carson city, California56728.081520.0-24792.092277.06527.017385.00.188400
16000US4816468Converse city, Texas54346.074891.0-20545.019705.06999.03545.00.179904
16000US3627485Freeport village, New York70816.085997.0-15181.043095.010098.013717.00.318297
16000US0684144West Carson CDP, California53826.068750.0-14924.021310.04097.02438.00.114406
16000US3613552Central Islip CDP, New York61287.075091.0-13804.036457.07244.09076.00.248951
16000US0615044Compton city, California27885.040189.0-12304.097495.01294.030568.00.313534
\n", 255 | "
" 256 | ], 257 | "text/plain": [ 258 | " name white_income black_income \\\n", 259 | "geoid \n", 260 | "16000US0672520 Soledad city, California 60441.0 147632.0 \n", 261 | "16000US3676089 Uniondale CDP, New York 36991.0 98148.0 \n", 262 | "16000US3676705 Valley Stream village, New York 78736.0 122880.0 \n", 263 | "16000US3624273 Elmont CDP, New York 63913.0 96223.0 \n", 264 | "16000US0611530 Carson city, California 56728.0 81520.0 \n", 265 | "16000US4816468 Converse city, Texas 54346.0 74891.0 \n", 266 | "16000US3627485 Freeport village, New York 70816.0 85997.0 \n", 267 | "16000US0684144 West Carson CDP, California 53826.0 68750.0 \n", 268 | "16000US3613552 Central Islip CDP, New York 61287.0 75091.0 \n", 269 | "16000US0615044 Compton city, California 27885.0 40189.0 \n", 270 | "\n", 271 | " gap total_pop white_pop black_pop black_pop_pct \n", 272 | "geoid \n", 273 | "16000US0672520 -87191.0 26251.0 3391.0 3312.0 0.126167 \n", 274 | "16000US3676089 -61157.0 25905.0 2416.0 11635.0 0.449141 \n", 275 | "16000US3676705 -44144.0 37618.0 13727.0 6763.0 0.179781 \n", 276 | "16000US3624273 -32310.0 39761.0 6260.0 19265.0 0.484520 \n", 277 | "16000US0611530 -24792.0 92277.0 6527.0 17385.0 0.188400 \n", 278 | "16000US4816468 -20545.0 19705.0 6999.0 3545.0 0.179904 \n", 279 | "16000US3627485 -15181.0 43095.0 10098.0 13717.0 0.318297 \n", 280 | "16000US0684144 -14924.0 21310.0 4097.0 2438.0 0.114406 \n", 281 | "16000US3613552 -13804.0 36457.0 7244.0 9076.0 0.248951 \n", 282 | "16000US0615044 -12304.0 97495.0 1294.0 30568.0 0.313534 " 283 | ] 284 | }, 285 | "execution_count": 6, 286 | "metadata": {}, 287 | "output_type": "execute_result" 288 | } 289 | ], 290 | "source": [ 291 | "df2.head(10)" 292 | ] 293 | }, 294 | { 295 | "cell_type": "markdown", 296 | "metadata": {}, 297 | "source": [ 298 | "_The paragraphs below refer to places which are no longer on the top 10 list after I updated to align with the tables FiveThirtyEight used for their chart. They are places with a large gap in favor of the black population, but they are too small to be included in the ACS 3-year estimates. I don't have time at the moment to investigate the ones which made this top ten list._\n", 299 | "\n", 300 | "I don't know much about Maryland, so I don't know what the deal is with [Kingstown](http://censusreporter.org/profiles/16000US2444325). It's only about [30 mi. from Baltimore](http://www.distance-cities.com/search?from=Baltimore%2C+MD&to=Kingstown%2C+MD%2C+United+States) \"as the crow flies,\" but more than 75 by roads because of the Chesapeake Bay.\n", 301 | "\n", 302 | "I'm from Ohio, but near Cleveland, so I never knew about [Wilberforce](http://censusreporter.org/profiles/16000US3985092-wilberforce-oh/). As the home of two historically black colleges, I am guessing that the administration and top faculty help account for the gap.\n", 303 | "\n" 304 | ] 305 | }, 306 | { 307 | "cell_type": "code", 308 | "execution_count": 7, 309 | "metadata": {}, 310 | "outputs": [ 311 | { 312 | "data": { 313 | "text/html": [ 314 | "
\n", 315 | "\n", 316 | " \n", 317 | " \n", 318 | " \n", 319 | " \n", 320 | " \n", 321 | " \n", 322 | " \n", 323 | " \n", 324 | " \n", 325 | " \n", 326 | " \n", 327 | " \n", 328 | " \n", 329 | " \n", 330 | " \n", 331 | " \n", 332 | " \n", 333 | " \n", 334 | " \n", 335 | " \n", 336 | " \n", 337 | " \n", 338 | " \n", 339 | " \n", 340 | " \n", 341 | " \n", 342 | " \n", 343 | " \n", 344 | " \n", 345 | " \n", 346 | " \n", 347 | " \n", 348 | " \n", 349 | " \n", 350 | " \n", 351 | " \n", 352 | " \n", 353 | " \n", 354 | " \n", 355 | " \n", 356 | " \n", 357 | " \n", 358 | " \n", 359 | " \n", 360 | " \n", 361 | " \n", 362 | " \n", 363 | " \n", 364 | " \n", 365 | " \n", 366 | " \n", 367 | " \n", 368 | " \n", 369 | " \n", 370 | " \n", 371 | " \n", 372 | " \n", 373 | " \n", 374 | " \n", 375 | "
namewhite_incomeblack_incomegaptotal_popwhite_popblack_popblack_pop_pct
geoid
16000US0624680Fontana city, California76469.079154.0-2685.0201293.029249.020638.00.102527
16000US0660466Rialto city, California46141.049056.0-2915.0101434.011722.014618.00.144113
16000US4856348Pearland city, Texas86944.096335.0-9391.098123.045309.017236.00.175657
\n", 376 | "
" 377 | ], 378 | "text/plain": [ 379 | " name white_income black_income gap \\\n", 380 | "geoid \n", 381 | "16000US0624680 Fontana city, California 76469.0 79154.0 -2685.0 \n", 382 | "16000US0660466 Rialto city, California 46141.0 49056.0 -2915.0 \n", 383 | "16000US4856348 Pearland city, Texas 86944.0 96335.0 -9391.0 \n", 384 | "\n", 385 | " total_pop white_pop black_pop black_pop_pct \n", 386 | "geoid \n", 387 | "16000US0624680 201293.0 29249.0 20638.0 0.102527 \n", 388 | "16000US0660466 101434.0 11722.0 14618.0 0.144113 \n", 389 | "16000US4856348 98123.0 45309.0 17236.0 0.175657 " 390 | ] 391 | }, 392 | "execution_count": 7, 393 | "metadata": {}, 394 | "output_type": "execute_result" 395 | } 396 | ], 397 | "source": [ 398 | "df2.sort_values(by='total_pop',ascending=False).head(3)" 399 | ] 400 | }, 401 | { 402 | "cell_type": "markdown", 403 | "metadata": {}, 404 | "source": [ 405 | "It turns out that the gap for the biggest places is not too big. Maybe we should filter by some factor." 406 | ] 407 | }, 408 | { 409 | "cell_type": "code", 410 | "execution_count": 8, 411 | "metadata": {}, 412 | "outputs": [ 413 | { 414 | "data": { 415 | "text/html": [ 416 | "
\n", 417 | "\n", 418 | " \n", 419 | " \n", 420 | " \n", 421 | " \n", 422 | " \n", 423 | " \n", 424 | " \n", 425 | " \n", 426 | " \n", 427 | " \n", 428 | " \n", 429 | " \n", 430 | " \n", 431 | " \n", 432 | " \n", 433 | " \n", 434 | " \n", 435 | " \n", 436 | " \n", 437 | " \n", 438 | " \n", 439 | " \n", 440 | " \n", 441 | " \n", 442 | " \n", 443 | " \n", 444 | " \n", 445 | " \n", 446 | " \n", 447 | " \n", 448 | " \n", 449 | " \n", 450 | " \n", 451 | " \n", 452 | " \n", 453 | " \n", 454 | " \n", 455 | " \n", 456 | " \n", 457 | " \n", 458 | " \n", 459 | " \n", 460 | " \n", 461 | " \n", 462 | " \n", 463 | " \n", 464 | " \n", 465 | " \n", 466 | " \n", 467 | " \n", 468 | " \n", 469 | " \n", 470 | " \n", 471 | " \n", 472 | " \n", 473 | " \n", 474 | " \n", 475 | " \n", 476 | " \n", 477 | " \n", 478 | " \n", 479 | " \n", 480 | " \n", 481 | " \n", 482 | " \n", 483 | " \n", 484 | " \n", 485 | " \n", 486 | " \n", 487 | " \n", 488 | "
namewhite_incomeblack_incomegaptotal_popwhite_popblack_popblack_pop_pct
geoid
16000US3624273Elmont CDP, New York63913.096223.0-32310.039761.06260.019265.00.484520
16000US3676705Valley Stream village, New York78736.0122880.0-44144.037618.013727.06763.00.179781
16000US0672520Soledad city, California60441.0147632.0-87191.026251.03391.03312.00.126167
16000US3676089Uniondale CDP, New York36991.098148.0-61157.025905.02416.011635.00.449141
\n", 489 | "
" 490 | ], 491 | "text/plain": [ 492 | " name white_income black_income \\\n", 493 | "geoid \n", 494 | "16000US3624273 Elmont CDP, New York 63913.0 96223.0 \n", 495 | "16000US3676705 Valley Stream village, New York 78736.0 122880.0 \n", 496 | "16000US0672520 Soledad city, California 60441.0 147632.0 \n", 497 | "16000US3676089 Uniondale CDP, New York 36991.0 98148.0 \n", 498 | "\n", 499 | " gap total_pop white_pop black_pop black_pop_pct \n", 500 | "geoid \n", 501 | "16000US3624273 -32310.0 39761.0 6260.0 19265.0 0.484520 \n", 502 | "16000US3676705 -44144.0 37618.0 13727.0 6763.0 0.179781 \n", 503 | "16000US0672520 -87191.0 26251.0 3391.0 3312.0 0.126167 \n", 504 | "16000US3676089 -61157.0 25905.0 2416.0 11635.0 0.449141 " 505 | ] 506 | }, 507 | "execution_count": 8, 508 | "metadata": {}, 509 | "output_type": "execute_result" 510 | } 511 | ], 512 | "source": [ 513 | "df3 = df2[df2.gap*-1 > df2.white_income/2]\n", 514 | "df3.sort_values(by='total_pop',ascending=False).head() " 515 | ] 516 | }, 517 | { 518 | "cell_type": "code", 519 | "execution_count": 9, 520 | "metadata": { 521 | "collapsed": true 522 | }, 523 | "outputs": [], 524 | "source": [ 525 | "# Always clean up your database\n", 526 | "engine.dispose()" 527 | ] 528 | } 529 | ], 530 | "metadata": { 531 | "kernelspec": { 532 | "display_name": "Python 3", 533 | "language": "python", 534 | "name": "python3" 535 | }, 536 | "language_info": { 537 | "codemirror_mode": { 538 | "name": "ipython", 539 | "version": 3 540 | }, 541 | "file_extension": ".py", 542 | "mimetype": "text/x-python", 543 | "name": "python", 544 | "nbconvert_exporter": "python", 545 | "pygments_lexer": "ipython3", 546 | "version": "3.4.3" 547 | } 548 | }, 549 | "nbformat": 4, 550 | "nbformat_minor": 1 551 | } 552 | -------------------------------------------------------------------------------- /Cuyahoga Voting.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "Starting point:\n", 8 | "\n", 9 | "

Q: In which Cuyahoga County community did Trump win the most votes?
A: Cleveland, followed by Parma & Strongsville. pic.twitter.com/awUAUFFAHt

— Nick Castele (@NickCastele) August 26, 2016
\n", 10 | "\n", 11 | "\n", 12 | "\n", 13 | "I was curious about the *rate* of support, so I put together this notebook to work that out." 14 | ] 15 | }, 16 | { 17 | "cell_type": "code", 18 | "execution_count": 1, 19 | "metadata": {}, 20 | "outputs": [], 21 | "source": [ 22 | "from censusreporter_api import get_dataframe, search_places\n", 23 | "import pandas as pd" 24 | ] 25 | }, 26 | { 27 | "cell_type": "code", 28 | "execution_count": 2, 29 | "metadata": {}, 30 | "outputs": [], 31 | "source": [ 32 | "df = get_dataframe('b01003','160|05000US39035', include_moe=True)" 33 | ] 34 | }, 35 | { 36 | "cell_type": "code", 37 | "execution_count": 3, 38 | "metadata": {}, 39 | "outputs": [ 40 | { 41 | "data": { 42 | "text/html": [ 43 | "
\n", 44 | "\n", 45 | " \n", 46 | " \n", 47 | " \n", 48 | " \n", 49 | " \n", 50 | " \n", 51 | " \n", 52 | " \n", 53 | " \n", 54 | " \n", 55 | " \n", 56 | " \n", 57 | " \n", 58 | " \n", 59 | " \n", 60 | " \n", 61 | " \n", 62 | " \n", 63 | " \n", 64 | " \n", 65 | " \n", 66 | " \n", 67 | " \n", 68 | " \n", 69 | " \n", 70 | " \n", 71 | " \n", 72 | " \n", 73 | " \n", 74 | " \n", 75 | " \n", 76 | " \n", 77 | " \n", 78 | " \n", 79 | " \n", 80 | " \n", 81 | " \n", 82 | " \n", 83 | " \n", 84 | " \n", 85 | " \n", 86 | " \n", 87 | " \n", 88 | " \n", 89 | " \n", 90 | " \n", 91 | " \n", 92 | " \n", 93 | " \n", 94 | " \n", 95 | " \n", 96 | " \n", 97 | " \n", 98 | " \n", 99 | " \n", 100 | " \n", 101 | " \n", 102 | " \n", 103 | " \n", 104 | " \n", 105 | " \n", 106 | " \n", 107 | " \n", 108 | " \n", 109 | " \n", 110 | " \n", 111 | " \n", 112 | " \n", 113 | " \n", 114 | " \n", 115 | "
nameTotalTotal (error)
16000US3916000Cleveland, OH390584.047.0
16000US3961000Parma, OH80380.050.0
16000US3941664Lakewood, OH51155.028.0
16000US3925704Euclid, OH48105.039.0
16000US3916014Cleveland Heights, OH45388.046.0
16000US3975098Strongsville, OH44649.040.0
16000US3983622Westlake, OH32469.039.0
16000US3956882North Olmsted, OH32248.028.0
16000US3957008North Royalton, OH30321.027.0
16000US3929428Garfield Heights, OH28365.035.0
\n", 116 | "
" 117 | ], 118 | "text/plain": [ 119 | " name Total Total (error)\n", 120 | "16000US3916000 Cleveland, OH 390584.0 47.0\n", 121 | "16000US3961000 Parma, OH 80380.0 50.0\n", 122 | "16000US3941664 Lakewood, OH 51155.0 28.0\n", 123 | "16000US3925704 Euclid, OH 48105.0 39.0\n", 124 | "16000US3916014 Cleveland Heights, OH 45388.0 46.0\n", 125 | "16000US3975098 Strongsville, OH 44649.0 40.0\n", 126 | "16000US3983622 Westlake, OH 32469.0 39.0\n", 127 | "16000US3956882 North Olmsted, OH 32248.0 28.0\n", 128 | "16000US3957008 North Royalton, OH 30321.0 27.0\n", 129 | "16000US3929428 Garfield Heights, OH 28365.0 35.0" 130 | ] 131 | }, 132 | "execution_count": 3, 133 | "metadata": {}, 134 | "output_type": "execute_result" 135 | } 136 | ], 137 | "source": [ 138 | "df.sort_values(by='Total',ascending=False).head(10)" 139 | ] 140 | }, 141 | { 142 | "cell_type": "code", 143 | "execution_count": 4, 144 | "metadata": {}, 145 | "outputs": [], 146 | "source": [ 147 | "votes = pd.read_excel('cuyahoga_2012_votes.xls',sheetname=1)" 148 | ] 149 | }, 150 | { 151 | "cell_type": "code", 152 | "execution_count": 5, 153 | "metadata": {}, 154 | "outputs": [], 155 | "source": [ 156 | "sum_cols = list(votes)[2:9]\n", 157 | "votes['total'] = votes[sum_cols].sum(axis=1)" 158 | ] 159 | }, 160 | { 161 | "cell_type": "code", 162 | "execution_count": 6, 163 | "metadata": {}, 164 | "outputs": [], 165 | "source": [ 166 | "votes['place'] = votes['Precinct'].apply(lambda x: x.split('-')[0])" 167 | ] 168 | }, 169 | { 170 | "cell_type": "code", 171 | "execution_count": 7, 172 | "metadata": {}, 173 | "outputs": [], 174 | "source": [ 175 | "new_cols = ['unity','precinct','soc','ind','con','lib','dem','rep','gre','write-in','over','under','total','place']\n", 176 | "votes = votes.rename(columns=dict(zip(votes.columns,new_cols)))" 177 | ] 178 | }, 179 | { 180 | "cell_type": "code", 181 | "execution_count": 8, 182 | "metadata": {}, 183 | "outputs": [], 184 | "source": [ 185 | "by_place = votes[['place','dem','rep','total']].groupby(by='place').sum()" 186 | ] 187 | }, 188 | { 189 | "cell_type": "code", 190 | "execution_count": 9, 191 | "metadata": {}, 192 | "outputs": [], 193 | "source": [ 194 | "by_place['dem_pct'] = by_place['dem']/by_place['total']" 195 | ] 196 | }, 197 | { 198 | "cell_type": "code", 199 | "execution_count": 10, 200 | "metadata": {}, 201 | "outputs": [ 202 | { 203 | "data": { 204 | "text/html": [ 205 | "
\n", 206 | "\n", 207 | " \n", 208 | " \n", 209 | " \n", 210 | " \n", 211 | " \n", 212 | " \n", 213 | " \n", 214 | " \n", 215 | " \n", 216 | " \n", 217 | " \n", 218 | " \n", 219 | " \n", 220 | " \n", 221 | " \n", 222 | " \n", 223 | " \n", 224 | " \n", 225 | " \n", 226 | " \n", 227 | " \n", 228 | " \n", 229 | " \n", 230 | " \n", 231 | " \n", 232 | " \n", 233 | " \n", 234 | " \n", 235 | " \n", 236 | " \n", 237 | " \n", 238 | " \n", 239 | " \n", 240 | " \n", 241 | " \n", 242 | " \n", 243 | " \n", 244 | " \n", 245 | " \n", 246 | " \n", 247 | " \n", 248 | " \n", 249 | " \n", 250 | " \n", 251 | " \n", 252 | " \n", 253 | " \n", 254 | " \n", 255 | " \n", 256 | " \n", 257 | " \n", 258 | " \n", 259 | " \n", 260 | " \n", 261 | " \n", 262 | " \n", 263 | " \n", 264 | " \n", 265 | " \n", 266 | " \n", 267 | " \n", 268 | " \n", 269 | " \n", 270 | " \n", 271 | " \n", 272 | " \n", 273 | " \n", 274 | " \n", 275 | " \n", 276 | " \n", 277 | " \n", 278 | " \n", 279 | " \n", 280 | " \n", 281 | " \n", 282 | " \n", 283 | " \n", 284 | " \n", 285 | " \n", 286 | " \n", 287 | " \n", 288 | " \n", 289 | " \n", 290 | " \n", 291 | " \n", 292 | " \n", 293 | " \n", 294 | " \n", 295 | " \n", 296 | " \n", 297 | " \n", 298 | " \n", 299 | " \n", 300 | " \n", 301 | " \n", 302 | " \n", 303 | " \n", 304 | " \n", 305 | " \n", 306 | " \n", 307 | " \n", 308 | " \n", 309 | " \n", 310 | " \n", 311 | " \n", 312 | " \n", 313 | " \n", 314 | " \n", 315 | " \n", 316 | " \n", 317 | " \n", 318 | " \n", 319 | " \n", 320 | " \n", 321 | " \n", 322 | " \n", 323 | " \n", 324 | " \n", 325 | " \n", 326 | " \n", 327 | " \n", 328 | " \n", 329 | " \n", 330 | " \n", 331 | " \n", 332 | " \n", 333 | " \n", 334 | " \n", 335 | " \n", 336 | " \n", 337 | " \n", 338 | " \n", 339 | " \n", 340 | " \n", 341 | " \n", 342 | " \n", 343 | " \n", 344 | " \n", 345 | " \n", 346 | " \n", 347 | " \n", 348 | " \n", 349 | " \n", 350 | " \n", 351 | " \n", 352 | " \n", 353 | " \n", 354 | " \n", 355 | " \n", 356 | " \n", 357 | " \n", 358 | " \n", 359 | " \n", 360 | " \n", 361 | " \n", 362 | " \n", 363 | " \n", 364 | " \n", 365 | " \n", 366 | " \n", 367 | " \n", 368 | " \n", 369 | " \n", 370 | " \n", 371 | " \n", 372 | " \n", 373 | " \n", 374 | " \n", 375 | " \n", 376 | " \n", 377 | " \n", 378 | " \n", 379 | " \n", 380 | " \n", 381 | " \n", 382 | " \n", 383 | " \n", 384 | " \n", 385 | " \n", 386 | " \n", 387 | " \n", 388 | " \n", 389 | " \n", 390 | " \n", 391 | " \n", 392 | " \n", 393 | " \n", 394 | " \n", 395 | " \n", 396 | " \n", 397 | " \n", 398 | " \n", 399 | " \n", 400 | " \n", 401 | " \n", 402 | " \n", 403 | " \n", 404 | " \n", 405 | " \n", 406 | " \n", 407 | " \n", 408 | " \n", 409 | " \n", 410 | " \n", 411 | " \n", 412 | " \n", 413 | " \n", 414 | " \n", 415 | " \n", 416 | " \n", 417 | " \n", 418 | " \n", 419 | " \n", 420 | " \n", 421 | " \n", 422 | " \n", 423 | " \n", 424 | " \n", 425 | " \n", 426 | " \n", 427 | " \n", 428 | " \n", 429 | " \n", 430 | " \n", 431 | " \n", 432 | " \n", 433 | " \n", 434 | " \n", 435 | " \n", 436 | " \n", 437 | " \n", 438 | " \n", 439 | " \n", 440 | " \n", 441 | " \n", 442 | " \n", 443 | " \n", 444 | " \n", 445 | " \n", 446 | " \n", 447 | " \n", 448 | " \n", 449 | " \n", 450 | " \n", 451 | " \n", 452 | " \n", 453 | " \n", 454 | " \n", 455 | " \n", 456 | " \n", 457 | " \n", 458 | " \n", 459 | " \n", 460 | " \n", 461 | " \n", 462 | " \n", 463 | " \n", 464 | " \n", 465 | " \n", 466 | " \n", 467 | " \n", 468 | " \n", 469 | " \n", 470 | " \n", 471 | " \n", 472 | " \n", 473 | " \n", 474 | " \n", 475 | " \n", 476 | " \n", 477 | " \n", 478 | " \n", 479 | " \n", 480 | " \n", 481 | " \n", 482 | " \n", 483 | " \n", 484 | " \n", 485 | " \n", 486 | " \n", 487 | " \n", 488 | " \n", 489 | " \n", 490 | " \n", 491 | " \n", 492 | " \n", 493 | " \n", 494 | " \n", 495 | " \n", 496 | " \n", 497 | " \n", 498 | " \n", 499 | " \n", 500 | " \n", 501 | " \n", 502 | " \n", 503 | " \n", 504 | " \n", 505 | " \n", 506 | " \n", 507 | " \n", 508 | " \n", 509 | " \n", 510 | " \n", 511 | " \n", 512 | " \n", 513 | " \n", 514 | " \n", 515 | " \n", 516 | " \n", 517 | " \n", 518 | " \n", 519 | " \n", 520 | " \n", 521 | " \n", 522 | " \n", 523 | " \n", 524 | " \n", 525 | " \n", 526 | " \n", 527 | " \n", 528 | " \n", 529 | " \n", 530 | " \n", 531 | " \n", 532 | " \n", 533 | " \n", 534 | " \n", 535 | " \n", 536 | " \n", 537 | " \n", 538 | " \n", 539 | " \n", 540 | " \n", 541 | " \n", 542 | " \n", 543 | " \n", 544 | " \n", 545 | " \n", 546 | " \n", 547 | " \n", 548 | " \n", 549 | " \n", 550 | " \n", 551 | " \n", 552 | " \n", 553 | " \n", 554 | " \n", 555 | " \n", 556 | " \n", 557 | " \n", 558 | " \n", 559 | " \n", 560 | " \n", 561 | " \n", 562 | " \n", 563 | " \n", 564 | " \n", 565 | " \n", 566 | " \n", 567 | " \n", 568 | " \n", 569 | " \n", 570 | " \n", 571 | " \n", 572 | " \n", 573 | " \n", 574 | " \n", 575 | " \n", 576 | " \n", 577 | " \n", 578 | " \n", 579 | " \n", 580 | " \n", 581 | " \n", 582 | " \n", 583 | " \n", 584 | " \n", 585 | " \n", 586 | " \n", 587 | " \n", 588 | " \n", 589 | " \n", 590 | " \n", 591 | " \n", 592 | " \n", 593 | " \n", 594 | " \n", 595 | " \n", 596 | " \n", 597 | " \n", 598 | " \n", 599 | " \n", 600 | " \n", 601 | " \n", 602 | " \n", 603 | " \n", 604 | " \n", 605 | " \n", 606 | " \n", 607 | " \n", 608 | " \n", 609 | " \n", 610 | " \n", 611 | " \n", 612 | " \n", 613 | " \n", 614 | " \n", 615 | " \n", 616 | " \n", 617 | " \n", 618 | " \n", 619 | " \n", 620 | " \n", 621 | " \n", 622 | " \n", 623 | " \n", 624 | " \n", 625 | " \n", 626 | " \n", 627 | " \n", 628 | " \n", 629 | " \n", 630 | " \n", 631 | " \n", 632 | " \n", 633 | " \n", 634 | " \n", 635 | " \n", 636 | " \n", 637 | " \n", 638 | "
demreptotaldem_pct
place
HIGHLAND HILLS41224160.990385
EAST CLEVELAND881412489590.983815
WARRENSVILLE HTS754514577050.979234
NORTH RANDALL503325370.936685
LINNDALE292310.935484
BEDFORD HEIGHTS567142161140.927543
WOODMERE354383950.896203
MAPLE HEIGHTS110231323124040.888665
CLEVELAND152262186431722400.884011
OAKWOOD188224421380.880262
CLEVELAND HEIGHTS221164012263790.838394
EUCLID200644577248650.806917
SHAKER HEIGHTS142823354177620.804076
SOUTH EUCLID95132631122330.777651
GARFIELD HEIGHTS102663134135510.757582
BEDFORD5030155666560.755709
RICHMOND HEIGHTS4496146159910.750459
GLENWILLOW2851174040.705446
LAKEWOOD173567119249280.696245
NEWBURGH HEIGHTS5072197350.689796
BEACHWOOD4873231572260.674370
UNIVERSITY HEIGHTS4561216967770.673012
ORANGE139176421630.643088
BROOKLYN3316178751770.640525
BROOK PARK5611313888830.631656
BEREA5826353095050.612941
MAYFIELD HEIGHTS5631347191880.612865
BRATENAHL5823719610.605619
PARMA HEIGHTS5482363892500.592649
CUYAHOGA HEIGHTS1961463450.568116
PARMA2094215483370010.565985
LYNDHURST4795359384890.564849
FAIRVIEW PARK5291403794700.558712
NORTH OLMSTED92517613170590.542294
SOLON72036094134050.537337
BROOKLYN HEIGHTS4674138940.522371
PEPPER PIKE2084190840110.519571
OLMSTED FALLS2386215646100.517570
MIDDLEBURG HEIGHTS4209394382530.509996
OLMSTED TOWNSHIP3467324868140.508805
MORELAND HILLS1090110722170.491655
ROCKY RIVER60056377124990.480438
SEVEN HILLS3306358469870.473164
BAY VILLAGE4596519099050.464008
WALTON HILLS67479014800.455405
CHAGRIN FALLS1143136325240.452853
VALLEY VIEW59371513250.447547
STRONGSVILLE1120813700251920.444903
WESTLAKE803010068182550.439879
MAYFIELD VILLAGE871110719990.435718
NORTH ROYALTON69749041162270.429778
BROADVIEW HEIGHTS45456008106620.426280
HIGHLAND HEIGHTS2199298952240.420942
INDEPENDENCE1809263945090.401198
BRECKSVILLE3378514286250.391652
GATES MILLS546106616270.335587
BENTLEYVILLE2024286310.320127
CHAGRIN FALLS TWP2963920.315217
HUNTING VALLEY1013124160.242788
\n", 639 | "
" 640 | ], 641 | "text/plain": [ 642 | " dem rep total dem_pct\n", 643 | "place \n", 644 | "HIGHLAND HILLS 412 2 416 0.990385\n", 645 | "EAST CLEVELAND 8814 124 8959 0.983815\n", 646 | "WARRENSVILLE HTS 7545 145 7705 0.979234\n", 647 | "NORTH RANDALL 503 32 537 0.936685\n", 648 | "LINNDALE 29 2 31 0.935484\n", 649 | "BEDFORD HEIGHTS 5671 421 6114 0.927543\n", 650 | "WOODMERE 354 38 395 0.896203\n", 651 | "MAPLE HEIGHTS 11023 1323 12404 0.888665\n", 652 | "CLEVELAND 152262 18643 172240 0.884011\n", 653 | "OAKWOOD 1882 244 2138 0.880262\n", 654 | "CLEVELAND HEIGHTS 22116 4012 26379 0.838394\n", 655 | "EUCLID 20064 4577 24865 0.806917\n", 656 | "SHAKER HEIGHTS 14282 3354 17762 0.804076\n", 657 | "SOUTH EUCLID 9513 2631 12233 0.777651\n", 658 | "GARFIELD HEIGHTS 10266 3134 13551 0.757582\n", 659 | "BEDFORD 5030 1556 6656 0.755709\n", 660 | "RICHMOND HEIGHTS 4496 1461 5991 0.750459\n", 661 | "GLENWILLOW 285 117 404 0.705446\n", 662 | "LAKEWOOD 17356 7119 24928 0.696245\n", 663 | "NEWBURGH HEIGHTS 507 219 735 0.689796\n", 664 | "BEACHWOOD 4873 2315 7226 0.674370\n", 665 | "UNIVERSITY HEIGHTS 4561 2169 6777 0.673012\n", 666 | "ORANGE 1391 764 2163 0.643088\n", 667 | "BROOKLYN 3316 1787 5177 0.640525\n", 668 | "BROOK PARK 5611 3138 8883 0.631656\n", 669 | "BEREA 5826 3530 9505 0.612941\n", 670 | "MAYFIELD HEIGHTS 5631 3471 9188 0.612865\n", 671 | "BRATENAHL 582 371 961 0.605619\n", 672 | "PARMA HEIGHTS 5482 3638 9250 0.592649\n", 673 | "CUYAHOGA HEIGHTS 196 146 345 0.568116\n", 674 | "PARMA 20942 15483 37001 0.565985\n", 675 | "LYNDHURST 4795 3593 8489 0.564849\n", 676 | "FAIRVIEW PARK 5291 4037 9470 0.558712\n", 677 | "NORTH OLMSTED 9251 7613 17059 0.542294\n", 678 | "SOLON 7203 6094 13405 0.537337\n", 679 | "BROOKLYN HEIGHTS 467 413 894 0.522371\n", 680 | "PEPPER PIKE 2084 1908 4011 0.519571\n", 681 | "OLMSTED FALLS 2386 2156 4610 0.517570\n", 682 | "MIDDLEBURG HEIGHTS 4209 3943 8253 0.509996\n", 683 | "OLMSTED TOWNSHIP 3467 3248 6814 0.508805\n", 684 | "MORELAND HILLS 1090 1107 2217 0.491655\n", 685 | "ROCKY RIVER 6005 6377 12499 0.480438\n", 686 | "SEVEN HILLS 3306 3584 6987 0.473164\n", 687 | "BAY VILLAGE 4596 5190 9905 0.464008\n", 688 | "WALTON HILLS 674 790 1480 0.455405\n", 689 | "CHAGRIN FALLS 1143 1363 2524 0.452853\n", 690 | "VALLEY VIEW 593 715 1325 0.447547\n", 691 | "STRONGSVILLE 11208 13700 25192 0.444903\n", 692 | "WESTLAKE 8030 10068 18255 0.439879\n", 693 | "MAYFIELD VILLAGE 871 1107 1999 0.435718\n", 694 | "NORTH ROYALTON 6974 9041 16227 0.429778\n", 695 | "BROADVIEW HEIGHTS 4545 6008 10662 0.426280\n", 696 | "HIGHLAND HEIGHTS 2199 2989 5224 0.420942\n", 697 | "INDEPENDENCE 1809 2639 4509 0.401198\n", 698 | "BRECKSVILLE 3378 5142 8625 0.391652\n", 699 | "GATES MILLS 546 1066 1627 0.335587\n", 700 | "BENTLEYVILLE 202 428 631 0.320127\n", 701 | "CHAGRIN FALLS TWP 29 63 92 0.315217\n", 702 | "HUNTING VALLEY 101 312 416 0.242788" 703 | ] 704 | }, 705 | "execution_count": 10, 706 | "metadata": {}, 707 | "output_type": "execute_result" 708 | } 709 | ], 710 | "source": [ 711 | "by_place.sort_values(by='dem_pct',ascending=False)" 712 | ] 713 | }, 714 | { 715 | "cell_type": "markdown", 716 | "metadata": { 717 | "collapsed": true 718 | }, 719 | "source": [ 720 | "**Note (July 27, 2017)** I left this kind of half-done and now I'm not really motivated to finish the analysis, which I guess would be comparing pct democratic support change between 2012 and 2016. If someone wants to finish it up and make a pull request, go for it!\n" 721 | ] 722 | } 723 | ], 724 | "metadata": { 725 | "kernelspec": { 726 | "display_name": "Python 3", 727 | "language": "python", 728 | "name": "python3" 729 | }, 730 | "language_info": { 731 | "codemirror_mode": { 732 | "name": "ipython", 733 | "version": 3 734 | }, 735 | "file_extension": ".py", 736 | "mimetype": "text/x-python", 737 | "name": "python", 738 | "nbconvert_exporter": "python", 739 | "pygments_lexer": "ipython3", 740 | "version": "3.4.3" 741 | } 742 | }, 743 | "nbformat": 4, 744 | "nbformat_minor": 1 745 | } 746 | -------------------------------------------------------------------------------- /Big race changes.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# X-shaped race graphs\n", 8 | "\n", 9 | "Reading, I saw the statistic that a South-side Chicago neighborhood went from 90% white to 95% black in 30 years. If you graphed black and white population on a line, they'd cross in the middle like an X.\n", 10 | "\n", 11 | "I wondered if there were any interesting recent cases of that kind of shift, and decided to see how easy that is with [Census Reporter](https://censusreporter.org). This is a mostly through-composed notebook, with a little cleanup. Maybe it's useful to other folks, or at least to me when I'm trying to remember how I did something...\n", 12 | "\n", 13 | "## To begin...\n", 14 | "\n", 15 | "Census Reporter has [an API](https://api.censusreporter.org) but it only serves the most recent ACS. Since we're talking historical comparison, that isn't going to do it for this.\n", 16 | "\n", 17 | "However, we've created [postgres database dumps for all ACS data released so far](http://censusreporter.tumblr.com/post/73727555158/easier-access-to-acs-data) so that other people can use the data with less setup.\n", 18 | "\n", 19 | "This is not what most people would call easy, but it is straightforward once you have the tools installed. Instructions about installing postgres is out of scope here, but if you created a database on a running postgres server, the rest really is pretty easy.\n", 20 | "\n", 21 | "This assumes you created a database named `census` already.\n", 22 | "\n", 23 | "## Download the data\n", 24 | "\n", 25 | "\n", 26 | "The ACS 1-year database dumps are less than 500 MB, so dealing with them is pretty fast. The ACS 5-year database dumps are very large, and you should only mess with them if you need them for more than one project.\n", 27 | "\n", 28 | "To download the data, do something like this:\n", 29 | "\n", 30 | "```bash\n", 31 | "curl -O http://census-backup.s3.amazonaws.com/acs/2007/acs2007_1yr/acs2007_1yr_backup.sql.gz\n", 32 | "curl -O http://census-backup.s3.amazonaws.com/acs/2014/acs2014_1yr/acs2014_1yr_backup.sql.gz \n", 33 | "```\n", 34 | "\n", 35 | "Then, assuming you have created a database named `census` and that you don't need to specify any username, password or other connection details, do this:\n", 36 | "\n", 37 | "```bash\n", 38 | "gzcat acs2007_1yr_backup.sql.gz | psql census\n", 39 | "gzcat acs2014_1yr_backup.sql.gz | psql census\n", 40 | "```\n", 41 | "\n", 42 | "These take a few minutes, so be patient, and probably best to paste the lines one-at-a-time.\n", 43 | "\n", 44 | "But now we're ready to code. \n", 45 | "\n", 46 | "### connect to the database" 47 | ] 48 | }, 49 | { 50 | "cell_type": "code", 51 | "execution_count": 1, 52 | "metadata": { 53 | "collapsed": true 54 | }, 55 | "outputs": [], 56 | "source": [ 57 | "import pandas as pd\n", 58 | "from psycopg2 import connect\n", 59 | "con = connect(database='census')" 60 | ] 61 | }, 62 | { 63 | "cell_type": "markdown", 64 | "metadata": {}, 65 | "source": [ 66 | "### execute queries\n", 67 | "\n", 68 | "We want to consider race, which is a complicated subject, including in how the Census deals with it. At least for the span of the ACS, the questions are the same -- comparing back even just in the last few decades may mean a detour to brush up on how to compare when the questions were asked differently.\n", 69 | "\n", 70 | "\n", 71 | "You might start looking for the data we need in the Census Bureau's tables in the \"race\" topic. However, latino is counted as an \"ethnicity,\" and there's a separate topic for the tables which report that data. The best table for our analysis is [B03002: Hispanic or Latino Origin by Race](http://censusreporter.org/tables/B03002/)\n", 72 | "\n", 73 | "Here's how to read in that table from the two different Census years:" 74 | ] 75 | }, 76 | { 77 | "cell_type": "code", 78 | "execution_count": 2, 79 | "metadata": {}, 80 | "outputs": [], 81 | "source": [ 82 | "# We leave out summary level 500 -- congressional districts -- because they changed considerably between\n", 83 | "# 2007 and 2014.\n", 84 | "sql = \"\"\"\n", 85 | "select g.name, d.* \n", 86 | "from {schema}.geoheader g, {schema}.b03002 d\n", 87 | "where g.geoid = d.geoid\n", 88 | "and g.sumlevel != 500\n", 89 | "\"\"\"\n", 90 | "\n", 91 | "b03002_14 = pd.read_sql_query(sql.format(schema='acs2014_1yr'), con, index_col='geoid')\n", 92 | "b03002_07 = pd.read_sql_query(sql.format(schema='acs2007_1yr'), con, index_col='geoid')" 93 | ] 94 | }, 95 | { 96 | "cell_type": "markdown", 97 | "metadata": {}, 98 | "source": [ 99 | "### simplify the data\n", 100 | "\n", 101 | "When talking about race in the United States, the set of \"options\" is often boiled down to:\n", 102 | "\n", 103 | "* White\n", 104 | "* Black\n", 105 | "* Asian\n", 106 | "* Hispanic\n", 107 | "\n", 108 | "On a national level, this covers more than 95% of the population. Since we're looking at sub-national data, we shouldn't assume that the other categories aren't relevant, but we still, there are 22 columns in B03002, and that's a lot to deal with. \n", 109 | "\n", 110 | "\n", 138 | "\n", 139 | "(If you want to learn a little more about how race is handled in the ACS, check out [Census Reporter's \"Race and Hispanic Origin\" topic page](http://censusreporter.org/topics/race-hispanic/).)\n", 140 | "\n" 141 | ] 142 | }, 143 | { 144 | "cell_type": "markdown", 145 | "metadata": {}, 146 | "source": [ 147 | "For our purposes, we're going to count all Hispanic as a single group. For \"non-hispanic\", we'll collapse \"some other race\" and \"two or more races\" into \"other\". \n" 148 | ] 149 | }, 150 | { 151 | "cell_type": "code", 152 | "execution_count": 3, 153 | "metadata": { 154 | "collapsed": true 155 | }, 156 | "outputs": [], 157 | "source": [ 158 | "def simplifier(b03002,percentify=True):\n", 159 | " \"\"\"Given a dataframe with B03002 schema, reduce it to a simpler dataframe according to the rules described above\"\"\"\n", 160 | " newcols = {\n", 161 | " 'total': b03002['b03002001'],\n", 162 | " 'white': b03002['b03002003'],\n", 163 | " 'black': b03002['b03002004'],\n", 164 | " 'amerind': b03002['b03002005'],\n", 165 | " 'asian': b03002['b03002006'],\n", 166 | " 'pacific': b03002['b03002007'],\n", 167 | " 'other': b03002['b03002008'] + b03002['b03002009'],\n", 168 | " 'hisp': b03002['b03002012']\n", 169 | " }\n", 170 | " if percentify:\n", 171 | " total = newcols.pop('total')\n", 172 | " for col in newcols:\n", 173 | " newcols[col] = newcols[col]/total\n", 174 | " \n", 175 | " return pd.DataFrame.from_dict(newcols)\n", 176 | "\n", 177 | "race07 = simplifier(b03002_07)\n", 178 | "race14 = simplifier(b03002_14)\n", 179 | "\n", 180 | "race_chg = race14 - race07\n", 181 | "race_chg = race_chg.dropna()\n", 182 | "\n", 183 | "# it's nice to have the 'name' column at the front when spitting it out in the notebook. \n", 184 | "# Since we use the geoid for the dataframe index, we can comfortably mix and match data from different queries.\n", 185 | "race_chg.insert(0,'name', b03002_07['name'])\n" 186 | ] 187 | }, 188 | { 189 | "cell_type": "markdown", 190 | "metadata": {}, 191 | "source": [ 192 | "### Identify the places with most change\n", 193 | "\n", 194 | "So, which places had the biggest change in any given race? This is probably not a particularly savvy way to get that, but it gave me a chance to practice the `pandas` syntax for building up data for a `DataFrame` which isn't already assembled in a CSV or database table." 195 | ] 196 | }, 197 | { 198 | "cell_type": "code", 199 | "execution_count": 4, 200 | "metadata": {}, 201 | "outputs": [ 202 | { 203 | "data": { 204 | "text/html": [ 205 | "
\n", 206 | "\n", 207 | " \n", 208 | " \n", 209 | " \n", 210 | " \n", 211 | " \n", 212 | " \n", 213 | " \n", 214 | " \n", 215 | " \n", 216 | " \n", 217 | " \n", 218 | " \n", 219 | " \n", 220 | " \n", 221 | " \n", 222 | " \n", 223 | " \n", 224 | " \n", 225 | " \n", 226 | " \n", 227 | " \n", 228 | " \n", 229 | " \n", 230 | " \n", 231 | " \n", 232 | " \n", 233 | " \n", 234 | " \n", 235 | " \n", 236 | " \n", 237 | " \n", 238 | " \n", 239 | " \n", 240 | " \n", 241 | " \n", 242 | " \n", 243 | " \n", 244 | " \n", 245 | " \n", 246 | " \n", 247 | " \n", 248 | " \n", 249 | " \n", 250 | " \n", 251 | " \n", 252 | " \n", 253 | " \n", 254 | " \n", 255 | " \n", 256 | " \n", 257 | " \n", 258 | " \n", 259 | " \n", 260 | " \n", 261 | " \n", 262 | " \n", 263 | " \n", 264 | " \n", 265 | "
colnamevalue
geoid
79500US3500200amerindPUMA5 00200, New Mexico0.164586
79500US0608101asianPUMA5 08101, California0.428660
79500US0605500blackPUMA5 05500, California-0.392138
79500US0400122hispPUMA5 00122, Arizona0.607988
79500US4000100otherPUMA5 00100, Oklahoma0.093469
40000US43669pacificKailua (Honolulu County)--Kaneohe, HI Urbanize...-0.055974
79500US0400122whitePUMA5 00122, Arizona-0.649215
\n", 266 | "
" 267 | ], 268 | "text/plain": [ 269 | " col name \\\n", 270 | "geoid \n", 271 | "79500US3500200 amerind PUMA5 00200, New Mexico \n", 272 | "79500US0608101 asian PUMA5 08101, California \n", 273 | "79500US0605500 black PUMA5 05500, California \n", 274 | "79500US0400122 hisp PUMA5 00122, Arizona \n", 275 | "79500US4000100 other PUMA5 00100, Oklahoma \n", 276 | "40000US43669 pacific Kailua (Honolulu County)--Kaneohe, HI Urbanize... \n", 277 | "79500US0400122 white PUMA5 00122, Arizona \n", 278 | "\n", 279 | " value \n", 280 | "geoid \n", 281 | "79500US3500200 0.164586 \n", 282 | "79500US0608101 0.428660 \n", 283 | "79500US0605500 -0.392138 \n", 284 | "79500US0400122 0.607988 \n", 285 | "79500US4000100 0.093469 \n", 286 | "40000US43669 -0.055974 \n", 287 | "79500US0400122 -0.649215 " 288 | ] 289 | }, 290 | "execution_count": 4, 291 | "metadata": {}, 292 | "output_type": "execute_result" 293 | } 294 | ], 295 | "source": [ 296 | "index=[]\n", 297 | "summary = {'col':[],'value': [], 'name': []}\n", 298 | "for col in race_chg.columns:\n", 299 | " if col != 'name':\n", 300 | " top = race_chg[col].max()\n", 301 | " bot = race_chg[col].min()\n", 302 | " if abs(top) > abs(bot):\n", 303 | " val = top\n", 304 | " else:\n", 305 | " val = bot\n", 306 | " row = race_chg[race_chg[col] == val]\n", 307 | " summary['col'].append(col)\n", 308 | " summary['value'].append(val)\n", 309 | " summary['name'].append(row['name'].item()) # we don't want the index label so use item()\n", 310 | " index.append(row.index.tolist()[0]) # here's where we want the index/geoid\n", 311 | "\n", 312 | "summary = pd.DataFrame(summary,index=pd.Series(index,name='geoid'))\n", 313 | "summary" 314 | ] 315 | }, 316 | { 317 | "cell_type": "markdown", 318 | "metadata": {}, 319 | "source": [ 320 | "## a diversion\n", 321 | "\n", 322 | "Here I decided to try to get all the bits in a single dataframe, `race`. I don't remember why, but the merging didn't seem to work the way I expected at first. I may have just been making bonehead mistakes because now it looks fairly straightforward.\n", 323 | "\n", 324 | "Then I was curious about the spread of changes. I could have (more) easily just described the `race_chg` dataframe, but sometimes you choose a step based on where you're stepping from so the last line here is just a trick to select only the `chg` columns from the merged dataframe for a quick look at them." 325 | ] 326 | }, 327 | { 328 | "cell_type": "code", 329 | "execution_count": 5, 330 | "metadata": {}, 331 | "outputs": [ 332 | { 333 | "data": { 334 | "text/html": [ 335 | "
\n", 336 | "\n", 337 | " \n", 338 | " \n", 339 | " \n", 340 | " \n", 341 | " \n", 342 | " \n", 343 | " \n", 344 | " \n", 345 | " \n", 346 | " \n", 347 | " \n", 348 | " \n", 349 | " \n", 350 | " \n", 351 | " \n", 352 | " \n", 353 | " \n", 354 | " \n", 355 | " \n", 356 | " \n", 357 | " \n", 358 | " \n", 359 | " \n", 360 | " \n", 361 | " \n", 362 | " \n", 363 | " \n", 364 | " \n", 365 | " \n", 366 | " \n", 367 | " \n", 368 | " \n", 369 | " \n", 370 | " \n", 371 | " \n", 372 | " \n", 373 | " \n", 374 | " \n", 375 | " \n", 376 | " \n", 377 | " \n", 378 | " \n", 379 | " \n", 380 | " \n", 381 | " \n", 382 | " \n", 383 | " \n", 384 | " \n", 385 | " \n", 386 | " \n", 387 | " \n", 388 | " \n", 389 | " \n", 390 | " \n", 391 | " \n", 392 | " \n", 393 | " \n", 394 | " \n", 395 | " \n", 396 | " \n", 397 | " \n", 398 | " \n", 399 | " \n", 400 | " \n", 401 | " \n", 402 | " \n", 403 | " \n", 404 | " \n", 405 | " \n", 406 | " \n", 407 | " \n", 408 | " \n", 409 | " \n", 410 | " \n", 411 | " \n", 412 | " \n", 413 | " \n", 414 | " \n", 415 | " \n", 416 | " \n", 417 | " \n", 418 | " \n", 419 | " \n", 420 | " \n", 421 | " \n", 422 | " \n", 423 | " \n", 424 | " \n", 425 | " \n", 426 | " \n", 427 | " \n", 428 | " \n", 429 | " \n", 430 | " \n", 431 | "
amerind_chgasian_chgblack_chghisp_chgother_chgpacific_chgwhite_chg
count2080.0000002080.0000002080.0000002080.0000002080.0000002080.0000002080.000000
mean0.0001480.0087630.0000570.0242470.0066550.000357-0.040226
std0.0084540.0218300.0281300.0481140.0094390.0039030.054326
min-0.094654-0.120585-0.392138-0.452918-0.047881-0.055974-0.649215
25%-0.0013420.000975-0.0069420.0117460.002171-0.000352-0.055862
50%-0.0001960.0053390.0007800.0222890.0059540.000000-0.039391
75%0.0008790.0128100.0078660.0365630.0108560.000583-0.024016
max0.1645860.4286600.3709860.6079880.0934690.0478320.512265
\n", 432 | "
" 433 | ], 434 | "text/plain": [ 435 | " amerind_chg asian_chg black_chg hisp_chg other_chg \\\n", 436 | "count 2080.000000 2080.000000 2080.000000 2080.000000 2080.000000 \n", 437 | "mean 0.000148 0.008763 0.000057 0.024247 0.006655 \n", 438 | "std 0.008454 0.021830 0.028130 0.048114 0.009439 \n", 439 | "min -0.094654 -0.120585 -0.392138 -0.452918 -0.047881 \n", 440 | "25% -0.001342 0.000975 -0.006942 0.011746 0.002171 \n", 441 | "50% -0.000196 0.005339 0.000780 0.022289 0.005954 \n", 442 | "75% 0.000879 0.012810 0.007866 0.036563 0.010856 \n", 443 | "max 0.164586 0.428660 0.370986 0.607988 0.093469 \n", 444 | "\n", 445 | " pacific_chg white_chg \n", 446 | "count 2080.000000 2080.000000 \n", 447 | "mean 0.000357 -0.040226 \n", 448 | "std 0.003903 0.054326 \n", 449 | "min -0.055974 -0.649215 \n", 450 | "25% -0.000352 -0.055862 \n", 451 | "50% 0.000000 -0.039391 \n", 452 | "75% 0.000583 -0.024016 \n", 453 | "max 0.047832 0.512265 " 454 | ] 455 | }, 456 | "execution_count": 5, 457 | "metadata": {}, 458 | "output_type": "execute_result" 459 | } 460 | ], 461 | "source": [ 462 | "race = pd.merge(race07,race14,left_index=True,right_index=True,suffixes=('_07','_14'))\n", 463 | "race = race.merge(race_chg,left_index=True,right_index=True,suffixes=('','_chg'))\n", 464 | "race.insert(0,'name',race.pop('name'))\n", 465 | "race['total_07'] = b03002_07['b03002001']\n", 466 | "race['total_14'] = b03002_14['b03002001']\n", 467 | "race = race.merge(race_chg,left_index=True,right_index=True,suffixes=('','_chg'))\n", 468 | "race[[x for x in race.columns if x.endswith('_chg')]].describe()" 469 | ] 470 | }, 471 | { 472 | "cell_type": "markdown", 473 | "metadata": {}, 474 | "source": [ 475 | "I always like boxplots. These are pretty hard to read, but I still think they look cool, and I like how much they data they pack.\n", 476 | "\n", 477 | "Matplotlib on MacOS with virtualenv is often a headache, but this seems to work consistently. Bokeh doesn't have built-in boxplots, so this is what we've got. " 478 | ] 479 | }, 480 | { 481 | "cell_type": "code", 482 | "execution_count": 6, 483 | "metadata": {}, 484 | "outputs": [ 485 | { 486 | "name": "stderr", 487 | "output_type": "stream", 488 | "text": [ 489 | "/Users/germuska/.virtualenvs/notebooks/lib/python3.4/site-packages/matplotlib/font_manager.py:273: UserWarning: Matplotlib is building the font cache using fc-list. This may take a moment.\n", 490 | " warnings.warn('Matplotlib is building the font cache using fc-list. This may take a moment.')\n", 491 | "/Users/germuska/.virtualenvs/notebooks/lib/python3.4/site-packages/matplotlib/font_manager.py:273: UserWarning: Matplotlib is building the font cache using fc-list. This may take a moment.\n", 492 | " warnings.warn('Matplotlib is building the font cache using fc-list. This may take a moment.')\n" 493 | ] 494 | }, 495 | { 496 | "data": { 497 | "text/plain": [ 498 | "" 499 | ] 500 | }, 501 | "execution_count": 6, 502 | "metadata": {}, 503 | "output_type": "execute_result" 504 | }, 505 | { 506 | "data": { 507 | "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXkAAAEACAYAAABWLgY0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzt3X28XFV97/HPN4khaCJJysMRqAkSRO6tcooWcm9pE0of\nYkXBFinaB9NWS1vTQu0D6MvegC9LCbf35anFFlELtPRepVwNlKsEaJNTUSxBCSAkaMAcIZiUSIg8\nhBDC7/4xe072OcyZM3PmYe+1832/XoE9e9aZtWbPnt9es/Z6UERgZmbVNK3oApiZWe84yJuZVZiD\nvJlZhTnIm5lVmIO8mVmFOcibmVVYV4K8pGWSNkn6tqQLGzz/I5K+LGmDpPslLe9GvmZm1pw67Scv\naRrwbeB04HFgPXBuRGzKpVkJzIqID0k6FHgIOCIiXuwoczMza6obNfmTge9ExEhE7AU+B5w5Ls02\nYE62PQf4gQO8mVnvzejCaxwFPJp7/Bi1wJ/3aeBfJT0OzAZ+pQv5mpnZJPp14/VDwL0RcSTw48An\nJc3uU95mZgesbtTktwKvzT0+OtuX95PAXwBExMOSvgu8Abh7/ItJ8mQ6ZmZtigg12t+Nmvx6YJGk\nBZJmAucCN41LsxH4WQBJRwCvBx5pUtie/Fu5cmXPXrsf/1x+l9/lL74cZSx7Mx3X5CNin6QVwK3U\nLhqfjYiNks6rPR1XAX8JXC3pXkDAn0XEk53mbWZmzXWjuYaIuAU4fty+T+W2dwBv70ZeZmbWugNq\nxOvSpUuLLkJHXP5iufzFSrn8RZa948FQ3SYpylYmM7Myk0T08MarmZmVlIO8mVmFOcibmVWYg7yZ\nWYU5yJuZVZiDvJlZhTnIm5lVmIO8mVmFOcibmVWYg7yZWYU5yJuZVZiDvJlZhTnIm5lVmIO8mVmF\nOcibmVWYg7yZWYU5yJuZVVhXgrykZZI2Sfq2pAsnSLNU0j2SviVpbTfyNeundevWFV0Es7Z1HOQl\nTQOuAH4B+K/AuyW9YVyaQ4BPAmdExI8B7+o0X7N+c5C3FHWjJn8y8J2IGImIvcDngDPHpXkP8H8j\nYitAROzoQr5mZjaJGV14jaOAR3OPH6MW+PNeD7wia6aZDXwiIv6xC3mb9dS6detGa/CXXHLJ6P6l\nS5eydOnSYgpl1oZuBPlW8zkJ+BngVcCdku6MiM2NEl988cWj2/4yWZHGn3/5c9OsKPnKx2S6EeS3\n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\nYII=\n", 508 | "text/plain": [ 509 | "" 510 | ] 511 | }, 512 | "metadata": {}, 513 | "output_type": "display_data" 514 | } 515 | ], 516 | "source": [ 517 | "%matplotlib inline\n", 518 | "from matplotlib import pyplot as plt\n", 519 | "race_chg.plot(kind='box')" 520 | ] 521 | }, 522 | { 523 | "cell_type": "markdown", 524 | "metadata": {}, 525 | "source": [ 526 | "One conclusion I draw from some of these summaries is that the number of places with dramatic changes in the percent of native american, pacific islander, some other race and multiracial is few, so I'm leaving them out of the rest of the analysis." 527 | ] 528 | }, 529 | { 530 | "cell_type": "markdown", 531 | "metadata": {}, 532 | "source": [ 533 | "## Using a visualization to see the extremes\n", 534 | "\n", 535 | "It took me a bunch of time to get the tooltips going -- again, it seems simple now, but I was piecing bits together from online examples while translating, and it took some fiddling.\n", 536 | "\n", 537 | "Most to the point, it seems like you can't add tools like the hover tool when you use the `Scatter` class.\n", 538 | "\n", 539 | "I wanted to reduce the number of points plotted, so I decided to eliminate those which would cluster closest to the center line, which is essentially-no-change. I omitted from the chart places in the data where the net change in population for the given group was less than 20 percentage points, either more or less. \n" 540 | ] 541 | }, 542 | { 543 | "cell_type": "code", 544 | "execution_count": 7, 545 | "metadata": {}, 546 | "outputs": [ 547 | { 548 | "data": { 549 | "text/html": [ 550 | "\n", 551 | "
\n", 552 | " \n", 553 | " Loading BokehJS ...\n", 554 | "
" 555 | ] 556 | }, 557 | "metadata": {}, 558 | "output_type": "display_data" 559 | }, 560 | { 561 | "data": { 562 | "application/javascript": [ 563 | "\n", 564 | "(function(global) {\n", 565 | " function now() {\n", 566 | " return new Date();\n", 567 | " }\n", 568 | "\n", 569 | " if (typeof (window._bokeh_onload_callbacks) === \"undefined\") {\n", 570 | " window._bokeh_onload_callbacks = [];\n", 571 | " }\n", 572 | "\n", 573 | " function run_callbacks() {\n", 574 | " window._bokeh_onload_callbacks.forEach(function(callback) { callback() });\n", 575 | " delete window._bokeh_onload_callbacks\n", 576 | " console.info(\"Bokeh: all callbacks have finished\");\n", 577 | " }\n", 578 | "\n", 579 | " function load_libs(js_urls, callback) {\n", 580 | " window._bokeh_onload_callbacks.push(callback);\n", 581 | " if (window._bokeh_is_loading > 0) {\n", 582 | " console.log(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n", 583 | " return null;\n", 584 | " }\n", 585 | " if (js_urls == null || js_urls.length === 0) {\n", 586 | " run_callbacks();\n", 587 | " return null;\n", 588 | " }\n", 589 | " console.log(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n", 590 | " window._bokeh_is_loading = js_urls.length;\n", 591 | " for (var i = 0; i < js_urls.length; i++) {\n", 592 | " var url = js_urls[i];\n", 593 | " var s = document.createElement('script');\n", 594 | " s.src = url;\n", 595 | " s.async = false;\n", 596 | " s.onreadystatechange = s.onload = function() {\n", 597 | " window._bokeh_is_loading--;\n", 598 | " if (window._bokeh_is_loading === 0) {\n", 599 | " console.log(\"Bokeh: all BokehJS libraries loaded\");\n", 600 | " run_callbacks()\n", 601 | " }\n", 602 | " };\n", 603 | " s.onerror = function() {\n", 604 | " console.warn(\"failed to load library \" + url);\n", 605 | " };\n", 606 | " console.log(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", 607 | " document.getElementsByTagName(\"head\")[0].appendChild(s);\n", 608 | " }\n", 609 | " };\n", 610 | "\n", 611 | " var js_urls = ['https://cdn.pydata.org/bokeh/release/bokeh-0.11.1.min.js', 'https://cdn.pydata.org/bokeh/release/bokeh-widgets-0.11.1.min.js', 'https://cdn.pydata.org/bokeh/release/bokeh-compiler-0.11.1.min.js'];\n", 612 | "\n", 613 | " var inline_js = [\n", 614 | " function(Bokeh) {\n", 615 | " Bokeh.set_log_level(\"info\");\n", 616 | " },\n", 617 | " \n", 618 | " function(Bokeh) {\n", 619 | " Bokeh.$(\"#195707d2-e7a8-4a23-8c25-b28b21e886fa\").text(\"BokehJS successfully loaded\");\n", 620 | " },\n", 621 | " function(Bokeh) {\n", 622 | " console.log(\"Bokeh: injecting CSS: https://cdn.pydata.org/bokeh/release/bokeh-0.11.1.min.css\");\n", 623 | " Bokeh.embed.inject_css(\"https://cdn.pydata.org/bokeh/release/bokeh-0.11.1.min.css\");\n", 624 | " console.log(\"Bokeh: injecting CSS: https://cdn.pydata.org/bokeh/release/bokeh-widgets-0.11.1.min.css\");\n", 625 | " Bokeh.embed.inject_css(\"https://cdn.pydata.org/bokeh/release/bokeh-widgets-0.11.1.min.css\");\n", 626 | " }\n", 627 | " ];\n", 628 | "\n", 629 | " function run_inline_js() {\n", 630 | " for (var i = 0; i < inline_js.length; i++) {\n", 631 | " inline_js[i](window.Bokeh);\n", 632 | " }\n", 633 | " }\n", 634 | "\n", 635 | " if (window._bokeh_is_loading === 0) {\n", 636 | " console.log(\"Bokeh: BokehJS loaded, going straight to plotting\");\n", 637 | " run_inline_js();\n", 638 | " } else {\n", 639 | " load_libs(js_urls, function() {\n", 640 | " console.log(\"Bokeh: BokehJS plotting callback run at\", now());\n", 641 | " run_inline_js();\n", 642 | " });\n", 643 | " }\n", 644 | "}(this));" 645 | ] 646 | }, 647 | "metadata": {}, 648 | "output_type": "display_data" 649 | }, 650 | { 651 | "data": { 652 | "text/html": [ 653 | "\n", 654 | "\n", 655 | "
\n", 656 | "" 741 | ] 742 | }, 743 | "metadata": {}, 744 | "output_type": "display_data" 745 | }, 746 | { 747 | "data": { 748 | "text/html": [ 749 | "

<Bokeh Notebook handle for In[7]>

" 750 | ], 751 | "text/plain": [ 752 | "" 753 | ] 754 | }, 755 | "execution_count": 7, 756 | "metadata": {}, 757 | "output_type": "execute_result" 758 | } 759 | ], 760 | "source": [ 761 | "from bokeh.charts import Scatter, show, output_notebook\n", 762 | "from bokeh.plotting import figure\n", 763 | "from bokeh.models import HoverTool, PolyAnnotation\n", 764 | "from bokeh.models.sources import ColumnDataSource\n", 765 | "output_notebook()\n", 766 | "\n", 767 | "#scatterplot = Scatter(race, x='white_07', y='white_14', title=\"Pct white 2007 vs 2014\",\n", 768 | "# xlabel=\"2007 pct white\")\n", 769 | "# http://blog.rtwilson.com/bokeh-plots-with-dataframe-based-tooltips/\n", 770 | "hover = HoverTool(tooltips=[('name','@name'),\n", 771 | " ('geoid', '@geoid'),\n", 772 | " ('white', '@white_chg{1.11}'), \n", 773 | " ('black', '@black_chg{1.11}'),\n", 774 | " ('hisp', '@hisp_chg{1.11}'),\n", 775 | " ('asian', '@asian_chg{1.11}')])\n", 776 | "\n", 777 | "p = figure(plot_width=750, plot_height=750,\n", 778 | " title=\"larger swings\")\n", 779 | "p.add_tools(hover)\n", 780 | "\n", 781 | "_plot_configs = [\n", 782 | " ('white', 'red', 'circle'),\n", 783 | " ('black', 'blue', 'square'),\n", 784 | " ('hisp', 'green', 'triangle'),\n", 785 | " ('asian', 'brown', 'inverted_triangle')\n", 786 | "]\n", 787 | "\n", 788 | "for r, c, m in _plot_configs:\n", 789 | " x_col = (r+'_07')\n", 790 | " y_col = (r+'_14')\n", 791 | " chg_col = (r+'_chg')\n", 792 | " race_for_plot = race[(race[chg_col].abs() > 0.2)]\n", 793 | " p.scatter(x=x_col, y=y_col, size=10, color=c, marker=m, source=ColumnDataSource(race_for_plot), legend=chg_col)\n", 794 | "\n", 795 | "\n", 796 | "p.xaxis.axis_label = '2007 pct of population'\n", 797 | "p.yaxis.axis_label = '2014 pct'\n", 798 | "\n", 799 | "# these just don't work!\n", 800 | "# drop_anno = PolyAnnotation(plot=p, xs=[.2, .4, .4, .2], ys=[.2, .2, .4, .4], fill_alpha=0.1, fill_color='red')\n", 801 | "#growth_anno = PolyAnnotation(plot=p, bottom=180, fill_alpha=0.1, fill_color='green')\n", 802 | "\n", 803 | "#p.renderers.extend([drop_anno, ])\n", 804 | "\n", 805 | "show(p)\n" 806 | ] 807 | }, 808 | { 809 | "cell_type": "markdown", 810 | "metadata": {}, 811 | "source": [ 812 | "Details on formatting the tooltips for Bokeh are not super easy to find. I had to hunt around to figure out how to format the change floats to have only two decimal places. I'm still not sure what to do about really long names, like _Philadelphia, PA Metro Division; Philadelphia-Camden-Wilmington, PA-NJ-DE-MD Metro Area_." 813 | ] 814 | }, 815 | { 816 | "cell_type": "markdown", 817 | "metadata": {}, 818 | "source": [ 819 | "### Lists instead of Charts\n", 820 | "\n", 821 | "Below are those places as a list, instead of on the chart. Broken up by race because again, I didn't come up with a clever way to say \"any row where the absolute value of any of these values is greater than 0.2\"" 822 | ] 823 | }, 824 | { 825 | "cell_type": "code", 826 | "execution_count": 8, 827 | "metadata": {}, 828 | "outputs": [ 829 | { 830 | "data": { 831 | "text/html": [ 832 | "
\n", 833 | "\n", 834 | " \n", 835 | " \n", 836 | " \n", 837 | " \n", 838 | " \n", 839 | " \n", 840 | " \n", 841 | " \n", 842 | " \n", 843 | " \n", 844 | " \n", 845 | " \n", 846 | " \n", 847 | " \n", 848 | " \n", 849 | " \n", 850 | " \n", 851 | " \n", 852 | " \n", 853 | " \n", 854 | " \n", 855 | " \n", 856 | " \n", 857 | " \n", 858 | " \n", 859 | " \n", 860 | " \n", 861 | " \n", 862 | " \n", 863 | " \n", 864 | " \n", 865 | " \n", 866 | " \n", 867 | " \n", 868 | " \n", 869 | " \n", 870 | " \n", 871 | " \n", 872 | " \n", 873 | " \n", 874 | " \n", 875 | " \n", 876 | " \n", 877 | " \n", 878 | " \n", 879 | " \n", 880 | " \n", 881 | " \n", 882 | " \n", 883 | " \n", 884 | " \n", 885 | " \n", 886 | " \n", 887 | " \n", 888 | " \n", 889 | " \n", 890 | " \n", 891 | " \n", 892 | " \n", 893 | " \n", 894 | " \n", 895 | " \n", 896 | " \n", 897 | " \n", 898 | " \n", 899 | " \n", 900 | " \n", 901 | " \n", 902 | " \n", 903 | " \n", 904 | " \n", 905 | " \n", 906 | " \n", 907 | " \n", 908 | " \n", 909 | " \n", 910 | " \n", 911 | " \n", 912 | " \n", 913 | " \n", 914 | " \n", 915 | " \n", 916 | " \n", 917 | " \n", 918 | " \n", 919 | "
nameblack_07black_14black_chgtotal_07total_14
geoid
79500US0605500PUMA5 05500, California0.4141260.021988-0.392138106581.0141667.0
79500US2503303PUMA5 03303, Massachusetts0.6017720.258776-0.342995115710.0112634.0
79500US2503304PUMA5 03304, Massachusetts0.1819440.5529300.370986117844.0137728.0
79500US4802308PUMA5 02308, Texas0.4198910.106989-0.312901179311.0105889.0
79500US4802504PUMA5 02504, Texas0.0540910.3215090.267418226857.0104588.0
79500US4803501PUMA5 03501, Texas0.0347600.3013640.266604115420.0166390.0
79500US4804625PUMA5 04625, Texas0.0081530.2217980.213644153925.0114140.0
\n", 920 | "
" 921 | ], 922 | "text/plain": [ 923 | " name black_07 black_14 black_chg \\\n", 924 | "geoid \n", 925 | "79500US0605500 PUMA5 05500, California 0.414126 0.021988 -0.392138 \n", 926 | "79500US2503303 PUMA5 03303, Massachusetts 0.601772 0.258776 -0.342995 \n", 927 | "79500US2503304 PUMA5 03304, Massachusetts 0.181944 0.552930 0.370986 \n", 928 | "79500US4802308 PUMA5 02308, Texas 0.419891 0.106989 -0.312901 \n", 929 | "79500US4802504 PUMA5 02504, Texas 0.054091 0.321509 0.267418 \n", 930 | "79500US4803501 PUMA5 03501, Texas 0.034760 0.301364 0.266604 \n", 931 | "79500US4804625 PUMA5 04625, Texas 0.008153 0.221798 0.213644 \n", 932 | "\n", 933 | " total_07 total_14 \n", 934 | "geoid \n", 935 | "79500US0605500 106581.0 141667.0 \n", 936 | "79500US2503303 115710.0 112634.0 \n", 937 | "79500US2503304 117844.0 137728.0 \n", 938 | "79500US4802308 179311.0 105889.0 \n", 939 | "79500US4802504 226857.0 104588.0 \n", 940 | "79500US4803501 115420.0 166390.0 \n", 941 | "79500US4804625 153925.0 114140.0 " 942 | ] 943 | }, 944 | "execution_count": 8, 945 | "metadata": {}, 946 | "output_type": "execute_result" 947 | } 948 | ], 949 | "source": [ 950 | "race[race['black_chg'].abs() > 0.2][['name','black_07','black_14','black_chg','total_07', 'total_14']]" 951 | ] 952 | }, 953 | { 954 | "cell_type": "code", 955 | "execution_count": 9, 956 | "metadata": {}, 957 | "outputs": [ 958 | { 959 | "data": { 960 | "text/html": [ 961 | "
\n", 962 | "\n", 963 | " \n", 964 | " \n", 965 | " \n", 966 | " \n", 967 | " \n", 968 | " \n", 969 | " \n", 970 | " \n", 971 | " \n", 972 | " \n", 973 | " \n", 974 | " \n", 975 | " \n", 976 | " \n", 977 | " \n", 978 | " \n", 979 | " \n", 980 | " \n", 981 | " \n", 982 | " \n", 983 | " \n", 984 | " \n", 985 | " \n", 986 | " \n", 987 | " \n", 988 | " \n", 989 | " \n", 990 | " \n", 991 | " \n", 992 | " \n", 993 | " \n", 994 | " \n", 995 | " \n", 996 | " \n", 997 | " \n", 998 | " \n", 999 | " \n", 1000 | " \n", 1001 | " \n", 1002 | " \n", 1003 | " \n", 1004 | " \n", 1005 | " \n", 1006 | " \n", 1007 | " \n", 1008 | " \n", 1009 | " \n", 1010 | " \n", 1011 | " \n", 1012 | " \n", 1013 | " \n", 1014 | " \n", 1015 | " \n", 1016 | " \n", 1017 | " \n", 1018 | " \n", 1019 | " \n", 1020 | " \n", 1021 | "
nameasian_07asian_14asian_chgtotal_07total_14
geoid
79500US0608101PUMA5 08101, California0.0411380.4697990.428660240360.0149579.0
79500US0608102PUMA5 08102, California0.0820520.3538310.271779130844.0122683.0
79500US0608103PUMA5 08103, California0.0110720.2608090.249737148930.0104728.0
79500US2701303PUMA5 01303, Minnesota0.0304090.2411260.210717115230.0135506.0
\n", 1022 | "
" 1023 | ], 1024 | "text/plain": [ 1025 | " name asian_07 asian_14 asian_chg \\\n", 1026 | "geoid \n", 1027 | "79500US0608101 PUMA5 08101, California 0.041138 0.469799 0.428660 \n", 1028 | "79500US0608102 PUMA5 08102, California 0.082052 0.353831 0.271779 \n", 1029 | "79500US0608103 PUMA5 08103, California 0.011072 0.260809 0.249737 \n", 1030 | "79500US2701303 PUMA5 01303, Minnesota 0.030409 0.241126 0.210717 \n", 1031 | "\n", 1032 | " total_07 total_14 \n", 1033 | "geoid \n", 1034 | "79500US0608101 240360.0 149579.0 \n", 1035 | "79500US0608102 130844.0 122683.0 \n", 1036 | "79500US0608103 148930.0 104728.0 \n", 1037 | "79500US2701303 115230.0 135506.0 " 1038 | ] 1039 | }, 1040 | "execution_count": 9, 1041 | "metadata": {}, 1042 | "output_type": "execute_result" 1043 | } 1044 | ], 1045 | "source": [ 1046 | "race[race['asian_chg'].abs() > 0.2][['name','asian_07','asian_14','asian_chg','total_07', 'total_14']]" 1047 | ] 1048 | }, 1049 | { 1050 | "cell_type": "code", 1051 | "execution_count": 10, 1052 | "metadata": {}, 1053 | "outputs": [ 1054 | { 1055 | "data": { 1056 | "text/html": [ 1057 | "
\n", 1058 | "\n", 1059 | " \n", 1060 | " \n", 1061 | " \n", 1062 | " \n", 1063 | " \n", 1064 | " \n", 1065 | " \n", 1066 | " \n", 1067 | " \n", 1068 | " \n", 1069 | " \n", 1070 | " \n", 1071 | " \n", 1072 | " \n", 1073 | " \n", 1074 | " \n", 1075 | " \n", 1076 | " \n", 1077 | " \n", 1078 | " \n", 1079 | " \n", 1080 | " \n", 1081 | " \n", 1082 | " \n", 1083 | " \n", 1084 | " \n", 1085 | " \n", 1086 | " \n", 1087 | " \n", 1088 | " \n", 1089 | " \n", 1090 | " \n", 1091 | " \n", 1092 | " \n", 1093 | " \n", 1094 | " \n", 1095 | " \n", 1096 | " \n", 1097 | " \n", 1098 | " \n", 1099 | " \n", 1100 | " \n", 1101 | " \n", 1102 | " \n", 1103 | " \n", 1104 | " \n", 1105 | " \n", 1106 | " \n", 1107 | " \n", 1108 | " \n", 1109 | " \n", 1110 | " \n", 1111 | " \n", 1112 | " \n", 1113 | " \n", 1114 | " \n", 1115 | " \n", 1116 | " \n", 1117 | " \n", 1118 | " \n", 1119 | " \n", 1120 | " \n", 1121 | " \n", 1122 | " \n", 1123 | " \n", 1124 | " \n", 1125 | " \n", 1126 | " \n", 1127 | " \n", 1128 | " \n", 1129 | " \n", 1130 | " \n", 1131 | " \n", 1132 | " \n", 1133 | " \n", 1134 | " \n", 1135 | " \n", 1136 | " \n", 1137 | " \n", 1138 | " \n", 1139 | " \n", 1140 | " \n", 1141 | " \n", 1142 | " \n", 1143 | " \n", 1144 | " \n", 1145 | " \n", 1146 | " \n", 1147 | " \n", 1148 | " \n", 1149 | " \n", 1150 | " \n", 1151 | " \n", 1152 | " \n", 1153 | " \n", 1154 | " \n", 1155 | " \n", 1156 | " \n", 1157 | " \n", 1158 | " \n", 1159 | " \n", 1160 | " \n", 1161 | " \n", 1162 | " \n", 1163 | " \n", 1164 | " \n", 1165 | " \n", 1166 | " \n", 1167 | " \n", 1168 | " \n", 1169 | " \n", 1170 | " \n", 1171 | " \n", 1172 | " \n", 1173 | " \n", 1174 | " \n", 1175 | " \n", 1176 | " \n", 1177 | " \n", 1178 | " \n", 1179 | " \n", 1180 | " \n", 1181 | " \n", 1182 | " \n", 1183 | " \n", 1184 | " \n", 1185 | " \n", 1186 | " \n", 1187 | " \n", 1188 | " \n", 1189 | " \n", 1190 | " \n", 1191 | " \n", 1192 | " \n", 1193 | " \n", 1194 | " \n", 1195 | " \n", 1196 | " \n", 1197 | " \n", 1198 | " \n", 1199 | " \n", 1200 | " \n", 1201 | " \n", 1202 | " \n", 1203 | " \n", 1204 | " \n", 1205 | " \n", 1206 | " \n", 1207 | " \n", 1208 | " \n", 1209 | " \n", 1210 | " \n", 1211 | " \n", 1212 | " \n", 1213 | " \n", 1214 | " \n", 1215 | " \n", 1216 | " \n", 1217 | " \n", 1218 | " \n", 1219 | " \n", 1220 | " \n", 1221 | " \n", 1222 | " \n", 1223 | " \n", 1224 | " \n", 1225 | " \n", 1226 | " \n", 1227 | " \n", 1228 | " \n", 1229 | " \n", 1230 | " \n", 1231 | " \n", 1232 | " \n", 1233 | " \n", 1234 | " \n", 1235 | " \n", 1236 | " \n", 1237 | " \n", 1238 | " \n", 1239 | " \n", 1240 | " \n", 1241 | " \n", 1242 | " \n", 1243 | " \n", 1244 | " \n", 1245 | " \n", 1246 | " \n", 1247 | " \n", 1248 | " \n", 1249 | " \n", 1250 | " \n", 1251 | " \n", 1252 | " \n", 1253 | " \n", 1254 | " \n", 1255 | " \n", 1256 | " \n", 1257 | " \n", 1258 | " \n", 1259 | " \n", 1260 | " \n", 1261 | " \n", 1262 | " \n", 1263 | " \n", 1264 | " \n", 1265 | " \n", 1266 | " \n", 1267 | " \n", 1268 | " \n", 1269 | " \n", 1270 | " \n", 1271 | " \n", 1272 | " \n", 1273 | " \n", 1274 | " \n", 1275 | " \n", 1276 | " \n", 1277 | " \n", 1278 | " \n", 1279 | "
namehisp_07hisp_14hisp_chgtotal_07total_14
geoid
79500US0400103PUMA5 00103, Arizona0.1862700.4796990.293429239088.0112433.0
79500US0400109PUMA5 00109, Arizona0.5127360.197885-0.314852174813.0111939.0
79500US0400115PUMA5 00115, Arizona0.4618150.245164-0.216651161229.0104583.0
79500US0400117PUMA5 00117, Arizona0.6659780.368033-0.297946153493.0108417.0
79500US0400118PUMA5 00118, Arizona0.7881940.541578-0.246616175321.0114495.0
79500US0400119PUMA5 00119, Arizona0.2741500.6588490.384699148404.0116957.0
79500US0400121PUMA5 00121, Arizona0.1713330.6677580.496425247273.0143892.0
79500US0400122PUMA5 00122, Arizona0.1650370.7730250.607988139399.094724.0
79500US0601301PUMA5 01301, California0.1785300.4934660.314936135266.0123269.0
79500US0601901PUMA5 01901, California0.5095230.7770630.267541126485.0155246.0
79500US0602500PUMA5 02500, California0.3618580.8227550.460897198473.0179091.0
79500US0606701PUMA5 06701, California0.5068640.158718-0.348146205935.0110101.0
79500US0608102PUMA5 08102, California0.6667560.327511-0.339245130844.0122683.0
79500US0608104PUMA5 08104, California0.5427390.168271-0.374467232493.0126807.0
79500US0608105PUMA5 08105, California0.5379850.253777-0.284208204539.0136269.0
79500US3500200PUMA5 00200, New Mexico0.6967220.243803-0.452918109167.098760.0
79500US3500300PUMA5 00300, New Mexico0.3602620.6224040.262142115416.0123068.0
79500US3603102PUMA5 03102, New York0.0681510.2779750.209823156857.0149618.0
79500US4802502PUMA5 02502, Texas0.4842730.187739-0.296534116455.0127022.0
79500US4803200PUMA5 03200, Texas0.3565760.5818050.225230126408.0114956.0
79500US4803400PUMA5 03400, Texas0.5536360.179002-0.37463495160.0179294.0
79500US4803501PUMA5 03501, Texas0.6598250.229695-0.430130115420.0166390.0
\n", 1280 | "
" 1281 | ], 1282 | "text/plain": [ 1283 | " name hisp_07 hisp_14 hisp_chg \\\n", 1284 | "geoid \n", 1285 | "79500US0400103 PUMA5 00103, Arizona 0.186270 0.479699 0.293429 \n", 1286 | "79500US0400109 PUMA5 00109, Arizona 0.512736 0.197885 -0.314852 \n", 1287 | "79500US0400115 PUMA5 00115, Arizona 0.461815 0.245164 -0.216651 \n", 1288 | "79500US0400117 PUMA5 00117, Arizona 0.665978 0.368033 -0.297946 \n", 1289 | "79500US0400118 PUMA5 00118, Arizona 0.788194 0.541578 -0.246616 \n", 1290 | "79500US0400119 PUMA5 00119, Arizona 0.274150 0.658849 0.384699 \n", 1291 | "79500US0400121 PUMA5 00121, Arizona 0.171333 0.667758 0.496425 \n", 1292 | "79500US0400122 PUMA5 00122, Arizona 0.165037 0.773025 0.607988 \n", 1293 | "79500US0601301 PUMA5 01301, California 0.178530 0.493466 0.314936 \n", 1294 | "79500US0601901 PUMA5 01901, California 0.509523 0.777063 0.267541 \n", 1295 | "79500US0602500 PUMA5 02500, California 0.361858 0.822755 0.460897 \n", 1296 | "79500US0606701 PUMA5 06701, California 0.506864 0.158718 -0.348146 \n", 1297 | "79500US0608102 PUMA5 08102, California 0.666756 0.327511 -0.339245 \n", 1298 | "79500US0608104 PUMA5 08104, California 0.542739 0.168271 -0.374467 \n", 1299 | "79500US0608105 PUMA5 08105, California 0.537985 0.253777 -0.284208 \n", 1300 | "79500US3500200 PUMA5 00200, New Mexico 0.696722 0.243803 -0.452918 \n", 1301 | "79500US3500300 PUMA5 00300, New Mexico 0.360262 0.622404 0.262142 \n", 1302 | "79500US3603102 PUMA5 03102, New York 0.068151 0.277975 0.209823 \n", 1303 | "79500US4802502 PUMA5 02502, Texas 0.484273 0.187739 -0.296534 \n", 1304 | "79500US4803200 PUMA5 03200, Texas 0.356576 0.581805 0.225230 \n", 1305 | "79500US4803400 PUMA5 03400, Texas 0.553636 0.179002 -0.374634 \n", 1306 | "79500US4803501 PUMA5 03501, Texas 0.659825 0.229695 -0.430130 \n", 1307 | "\n", 1308 | " total_07 total_14 \n", 1309 | "geoid \n", 1310 | "79500US0400103 239088.0 112433.0 \n", 1311 | "79500US0400109 174813.0 111939.0 \n", 1312 | "79500US0400115 161229.0 104583.0 \n", 1313 | "79500US0400117 153493.0 108417.0 \n", 1314 | "79500US0400118 175321.0 114495.0 \n", 1315 | "79500US0400119 148404.0 116957.0 \n", 1316 | "79500US0400121 247273.0 143892.0 \n", 1317 | "79500US0400122 139399.0 94724.0 \n", 1318 | "79500US0601301 135266.0 123269.0 \n", 1319 | "79500US0601901 126485.0 155246.0 \n", 1320 | "79500US0602500 198473.0 179091.0 \n", 1321 | "79500US0606701 205935.0 110101.0 \n", 1322 | "79500US0608102 130844.0 122683.0 \n", 1323 | "79500US0608104 232493.0 126807.0 \n", 1324 | "79500US0608105 204539.0 136269.0 \n", 1325 | "79500US3500200 109167.0 98760.0 \n", 1326 | "79500US3500300 115416.0 123068.0 \n", 1327 | "79500US3603102 156857.0 149618.0 \n", 1328 | "79500US4802502 116455.0 127022.0 \n", 1329 | "79500US4803200 126408.0 114956.0 \n", 1330 | "79500US4803400 95160.0 179294.0 \n", 1331 | "79500US4803501 115420.0 166390.0 " 1332 | ] 1333 | }, 1334 | "execution_count": 10, 1335 | "metadata": {}, 1336 | "output_type": "execute_result" 1337 | } 1338 | ], 1339 | "source": [ 1340 | "race[race['hisp_chg'].abs() > 0.2][['name','hisp_07','hisp_14','hisp_chg','total_07', 'total_14']]" 1341 | ] 1342 | }, 1343 | { 1344 | "cell_type": "code", 1345 | "execution_count": 11, 1346 | "metadata": { 1347 | "scrolled": false 1348 | }, 1349 | "outputs": [ 1350 | { 1351 | "data": { 1352 | "text/html": [ 1353 | "
\n", 1354 | "\n", 1355 | " \n", 1356 | " \n", 1357 | " \n", 1358 | " \n", 1359 | " \n", 1360 | " \n", 1361 | " \n", 1362 | " \n", 1363 | " \n", 1364 | " \n", 1365 | " \n", 1366 | " \n", 1367 | " \n", 1368 | " \n", 1369 | " \n", 1370 | " \n", 1371 | " \n", 1372 | " \n", 1373 | " \n", 1374 | " \n", 1375 | " \n", 1376 | " \n", 1377 | " \n", 1378 | " \n", 1379 | " \n", 1380 | " \n", 1381 | " \n", 1382 | " \n", 1383 | " \n", 1384 | " \n", 1385 | " \n", 1386 | " \n", 1387 | " \n", 1388 | " \n", 1389 | " \n", 1390 | " \n", 1391 | " \n", 1392 | " \n", 1393 | " \n", 1394 | " \n", 1395 | " \n", 1396 | " \n", 1397 | " \n", 1398 | " \n", 1399 | " \n", 1400 | " \n", 1401 | " \n", 1402 | " \n", 1403 | " \n", 1404 | " \n", 1405 | " \n", 1406 | " \n", 1407 | " \n", 1408 | " \n", 1409 | " \n", 1410 | " \n", 1411 | " \n", 1412 | " \n", 1413 | " \n", 1414 | " \n", 1415 | " \n", 1416 | " \n", 1417 | " \n", 1418 | " \n", 1419 | " \n", 1420 | " \n", 1421 | " \n", 1422 | " \n", 1423 | " \n", 1424 | " \n", 1425 | " \n", 1426 | " \n", 1427 | " \n", 1428 | " \n", 1429 | " \n", 1430 | " \n", 1431 | " \n", 1432 | " \n", 1433 | " \n", 1434 | " \n", 1435 | " \n", 1436 | " \n", 1437 | " \n", 1438 | " \n", 1439 | " \n", 1440 | " \n", 1441 | " \n", 1442 | " \n", 1443 | " \n", 1444 | " \n", 1445 | " \n", 1446 | " \n", 1447 | " \n", 1448 | " \n", 1449 | " \n", 1450 | " \n", 1451 | " \n", 1452 | " \n", 1453 | " \n", 1454 | " \n", 1455 | " \n", 1456 | " \n", 1457 | " \n", 1458 | " \n", 1459 | " \n", 1460 | " \n", 1461 | " \n", 1462 | " \n", 1463 | " \n", 1464 | " \n", 1465 | " \n", 1466 | " \n", 1467 | " \n", 1468 | " \n", 1469 | " \n", 1470 | " \n", 1471 | " \n", 1472 | " \n", 1473 | " \n", 1474 | " \n", 1475 | " \n", 1476 | " \n", 1477 | " \n", 1478 | " \n", 1479 | " \n", 1480 | " \n", 1481 | " \n", 1482 | " \n", 1483 | " \n", 1484 | " \n", 1485 | " \n", 1486 | " \n", 1487 | " \n", 1488 | " \n", 1489 | " \n", 1490 | " \n", 1491 | " \n", 1492 | " \n", 1493 | " \n", 1494 | " \n", 1495 | " \n", 1496 | " \n", 1497 | " \n", 1498 | " \n", 1499 | " \n", 1500 | " \n", 1501 | " \n", 1502 | " \n", 1503 | " \n", 1504 | " \n", 1505 | " \n", 1506 | " \n", 1507 | " \n", 1508 | " \n", 1509 | " \n", 1510 | " \n", 1511 | " \n", 1512 | " \n", 1513 | " \n", 1514 | " \n", 1515 | " \n", 1516 | " \n", 1517 | " \n", 1518 | " \n", 1519 | " \n", 1520 | " \n", 1521 | " \n", 1522 | " \n", 1523 | " \n", 1524 | " \n", 1525 | " \n", 1526 | " \n", 1527 | " \n", 1528 | " \n", 1529 | " \n", 1530 | " \n", 1531 | " \n", 1532 | " \n", 1533 | " \n", 1534 | " \n", 1535 | " \n", 1536 | " \n", 1537 | " \n", 1538 | " \n", 1539 | " \n", 1540 | " \n", 1541 | " \n", 1542 | " \n", 1543 | " \n", 1544 | " \n", 1545 | " \n", 1546 | " \n", 1547 | " \n", 1548 | " \n", 1549 | " \n", 1550 | " \n", 1551 | " \n", 1552 | " \n", 1553 | " \n", 1554 | " \n", 1555 | " \n", 1556 | " \n", 1557 | " \n", 1558 | " \n", 1559 | " \n", 1560 | " \n", 1561 | " \n", 1562 | " \n", 1563 | " \n", 1564 | " \n", 1565 | " \n", 1566 | " \n", 1567 | " \n", 1568 | " \n", 1569 | " \n", 1570 | " \n", 1571 | " \n", 1572 | " \n", 1573 | " \n", 1574 | " \n", 1575 | " \n", 1576 | " \n", 1577 | " \n", 1578 | " \n", 1579 | " \n", 1580 | " \n", 1581 | " \n", 1582 | " \n", 1583 | " \n", 1584 | " \n", 1585 | " \n", 1586 | " \n", 1587 | " \n", 1588 | " \n", 1589 | " \n", 1590 | " \n", 1591 | " \n", 1592 | " \n", 1593 | " \n", 1594 | " \n", 1595 | " \n", 1596 | " \n", 1597 | " \n", 1598 | " \n", 1599 | " \n", 1600 | " \n", 1601 | " \n", 1602 | " \n", 1603 | " \n", 1604 | " \n", 1605 | " \n", 1606 | " \n", 1607 | " \n", 1608 | " \n", 1609 | " \n", 1610 | " \n", 1611 | " \n", 1612 | " \n", 1613 | " \n", 1614 | " \n", 1615 | " \n", 1616 | " \n", 1617 | " \n", 1618 | " \n", 1619 | " \n", 1620 | " \n", 1621 | " \n", 1622 | " \n", 1623 | " \n", 1624 | " \n", 1625 | " \n", 1626 | " \n", 1627 | " \n", 1628 | " \n", 1629 | " \n", 1630 | " \n", 1631 | " \n", 1632 | " \n", 1633 | " \n", 1634 | " \n", 1635 | " \n", 1636 | " \n", 1637 | " \n", 1638 | " \n", 1639 | " \n", 1640 | " \n", 1641 | " \n", 1642 | " \n", 1643 | " \n", 1644 | " \n", 1645 | " \n", 1646 | " \n", 1647 | " \n", 1648 | " \n", 1649 | " \n", 1650 | " \n", 1651 | " \n", 1652 | " \n", 1653 | " \n", 1654 | " \n", 1655 | " \n", 1656 | " \n", 1657 | " \n", 1658 | " \n", 1659 | " \n", 1660 | " \n", 1661 | " \n", 1662 | " \n", 1663 | " \n", 1664 | " \n", 1665 | " \n", 1666 | " \n", 1667 | " \n", 1668 | " \n", 1669 | " \n", 1670 | " \n", 1671 | " \n", 1672 | " \n", 1673 | " \n", 1674 | " \n", 1675 | " \n", 1676 | " \n", 1677 | " \n", 1678 | " \n", 1679 | " \n", 1680 | " \n", 1681 | " \n", 1682 | " \n", 1683 | " \n", 1684 | " \n", 1685 | " \n", 1686 | " \n", 1687 | " \n", 1688 | " \n", 1689 | " \n", 1690 | " \n", 1691 | " \n", 1692 | " \n", 1693 | " \n", 1694 | " \n", 1695 | " \n", 1696 | " \n", 1697 | " \n", 1698 | " \n", 1699 | " \n", 1700 | " \n", 1701 | " \n", 1702 | " \n", 1703 | " \n", 1704 | " \n", 1705 | " \n", 1706 | " \n", 1707 | " \n", 1708 | " \n", 1709 | " \n", 1710 | " \n", 1711 | " \n", 1712 | " \n", 1713 | " \n", 1714 | " \n", 1715 | " \n", 1716 | " \n", 1717 | " \n", 1718 | " \n", 1719 | "
namewhite_07white_14white_chgtotal_07total_14
geoid
16000US4847892Mesquite city, Texas0.5287390.307210-0.221530126081.0144289.0
31400US3798037964Philadelphia, PA Metropolitan Division, Philad...0.6622790.443912-0.2183673887694.02123257.0
79500US0400103PUMA5 00103, Arizona0.7285180.406740-0.321778239088.0112433.0
79500US0400106PUMA5 00106, Arizona0.7558350.486296-0.26953995112.0123398.0
79500US0400108PUMA5 00108, Arizona0.7554080.552054-0.203354120850.0105593.0
79500US0400109PUMA5 00109, Arizona0.3540300.6214280.267398174813.0111939.0
79500US0400115PUMA5 00115, Arizona0.4330800.6529070.219828161229.0104583.0
79500US0400117PUMA5 00117, Arizona0.1781250.5200380.341913153493.0108417.0
79500US0400119PUMA5 00119, Arizona0.5476670.133314-0.414353148404.0116957.0
79500US0400121PUMA5 00121, Arizona0.7398460.157160-0.582687247273.0143892.0
79500US0400122PUMA5 00122, Arizona0.7641590.114944-0.649215139399.094724.0
79500US0601301PUMA5 01301, California0.3860170.121231-0.264786135266.0123269.0
79500US0602500PUMA5 02500, California0.5157430.122027-0.393715198473.0179091.0
79500US0603701PUMA5 03701, California0.7582810.508031-0.250249131781.0134472.0
79500US0603702PUMA5 03702, California0.7086220.440702-0.267920130655.0201617.0
79500US0605500PUMA5 05500, California0.0243100.5365750.512265106581.0141667.0
79500US0606101PUMA5 06101, California0.5044920.7090970.204605170510.0133835.0
79500US0606102PUMA5 06102, California0.5103910.7359330.225542140990.0115959.0
79500US0606701PUMA5 06701, California0.4100610.7516010.341539205935.0110101.0
79500US0608101PUMA5 08101, California0.5994880.233763-0.365726240360.0149579.0
79500US0608103PUMA5 08103, California0.7538040.495312-0.258492148930.0104728.0
79500US0608104PUMA5 08104, California0.2157660.5169510.301185232493.0126807.0
79500US0608105PUMA5 08105, California0.1166670.5286680.412000204539.0136269.0
79500US2503303PUMA5 03303, Massachusetts0.0892060.4812670.392061115710.0112634.0
79500US2503304PUMA5 03304, Massachusetts0.5395690.115997-0.423573117844.0137728.0
79500US3402301PUMA5 02301, New Jersey0.5114100.258935-0.252474200753.0120590.0
79500US3500200PUMA5 00200, New Mexico0.2136630.5002330.286569109167.098760.0
79500US3500300PUMA5 00300, New Mexico0.5662910.284282-0.282009115416.0123068.0
79500US3603102PUMA5 03102, New York0.8416140.553282-0.288331156857.0149618.0
79500US3700400PUMA5 00400, North Carolina0.8189560.609494-0.209462223526.0120185.0
79500US4802308PUMA5 02308, Texas0.1576030.4123000.254696179311.0105889.0
79500US4802313PUMA5 02313, Texas0.3422770.5649010.222624130403.0116870.0
79500US4802502PUMA5 02502, Texas0.2262500.4576840.231434116455.0127022.0
79500US4802504PUMA5 02504, Texas0.5257670.309175-0.216592226857.0104588.0
79500US4802507PUMA5 02507, Texas0.7355550.504637-0.230918156369.0125627.0
79500US4803400PUMA5 03400, Texas0.3869690.6999290.31295995160.0179294.0
79500US4805303PUMA5 05303, Texas0.5150040.265493-0.249511198111.0144000.0
97000US4830390MESQUITE INDEPENDENT SCHOOL DISTRICT , Texas0.5116510.298632-0.213019155778.0172483.0
\n", 1720 | "
" 1721 | ], 1722 | "text/plain": [ 1723 | " name \\\n", 1724 | "geoid \n", 1725 | "16000US4847892 Mesquite city, Texas \n", 1726 | "31400US3798037964 Philadelphia, PA Metropolitan Division, Philad... \n", 1727 | "79500US0400103 PUMA5 00103, Arizona \n", 1728 | "79500US0400106 PUMA5 00106, Arizona \n", 1729 | "79500US0400108 PUMA5 00108, Arizona \n", 1730 | "79500US0400109 PUMA5 00109, Arizona \n", 1731 | "79500US0400115 PUMA5 00115, Arizona \n", 1732 | "79500US0400117 PUMA5 00117, Arizona \n", 1733 | "79500US0400119 PUMA5 00119, Arizona \n", 1734 | "79500US0400121 PUMA5 00121, Arizona \n", 1735 | "79500US0400122 PUMA5 00122, Arizona \n", 1736 | "79500US0601301 PUMA5 01301, California \n", 1737 | "79500US0602500 PUMA5 02500, California \n", 1738 | "79500US0603701 PUMA5 03701, California \n", 1739 | "79500US0603702 PUMA5 03702, California \n", 1740 | "79500US0605500 PUMA5 05500, California \n", 1741 | "79500US0606101 PUMA5 06101, California \n", 1742 | "79500US0606102 PUMA5 06102, California \n", 1743 | "79500US0606701 PUMA5 06701, California \n", 1744 | "79500US0608101 PUMA5 08101, California \n", 1745 | "79500US0608103 PUMA5 08103, California \n", 1746 | "79500US0608104 PUMA5 08104, California \n", 1747 | "79500US0608105 PUMA5 08105, California \n", 1748 | "79500US2503303 PUMA5 03303, Massachusetts \n", 1749 | "79500US2503304 PUMA5 03304, Massachusetts \n", 1750 | "79500US3402301 PUMA5 02301, New Jersey \n", 1751 | "79500US3500200 PUMA5 00200, New Mexico \n", 1752 | "79500US3500300 PUMA5 00300, New Mexico \n", 1753 | "79500US3603102 PUMA5 03102, New York \n", 1754 | "79500US3700400 PUMA5 00400, North Carolina \n", 1755 | "79500US4802308 PUMA5 02308, Texas \n", 1756 | "79500US4802313 PUMA5 02313, Texas \n", 1757 | "79500US4802502 PUMA5 02502, Texas \n", 1758 | "79500US4802504 PUMA5 02504, Texas \n", 1759 | "79500US4802507 PUMA5 02507, Texas \n", 1760 | "79500US4803400 PUMA5 03400, Texas \n", 1761 | "79500US4805303 PUMA5 05303, Texas \n", 1762 | "97000US4830390 MESQUITE INDEPENDENT SCHOOL DISTRICT , Texas \n", 1763 | "\n", 1764 | " white_07 white_14 white_chg total_07 total_14 \n", 1765 | "geoid \n", 1766 | "16000US4847892 0.528739 0.307210 -0.221530 126081.0 144289.0 \n", 1767 | "31400US3798037964 0.662279 0.443912 -0.218367 3887694.0 2123257.0 \n", 1768 | "79500US0400103 0.728518 0.406740 -0.321778 239088.0 112433.0 \n", 1769 | "79500US0400106 0.755835 0.486296 -0.269539 95112.0 123398.0 \n", 1770 | "79500US0400108 0.755408 0.552054 -0.203354 120850.0 105593.0 \n", 1771 | "79500US0400109 0.354030 0.621428 0.267398 174813.0 111939.0 \n", 1772 | "79500US0400115 0.433080 0.652907 0.219828 161229.0 104583.0 \n", 1773 | "79500US0400117 0.178125 0.520038 0.341913 153493.0 108417.0 \n", 1774 | "79500US0400119 0.547667 0.133314 -0.414353 148404.0 116957.0 \n", 1775 | "79500US0400121 0.739846 0.157160 -0.582687 247273.0 143892.0 \n", 1776 | "79500US0400122 0.764159 0.114944 -0.649215 139399.0 94724.0 \n", 1777 | "79500US0601301 0.386017 0.121231 -0.264786 135266.0 123269.0 \n", 1778 | "79500US0602500 0.515743 0.122027 -0.393715 198473.0 179091.0 \n", 1779 | "79500US0603701 0.758281 0.508031 -0.250249 131781.0 134472.0 \n", 1780 | "79500US0603702 0.708622 0.440702 -0.267920 130655.0 201617.0 \n", 1781 | "79500US0605500 0.024310 0.536575 0.512265 106581.0 141667.0 \n", 1782 | "79500US0606101 0.504492 0.709097 0.204605 170510.0 133835.0 \n", 1783 | "79500US0606102 0.510391 0.735933 0.225542 140990.0 115959.0 \n", 1784 | "79500US0606701 0.410061 0.751601 0.341539 205935.0 110101.0 \n", 1785 | "79500US0608101 0.599488 0.233763 -0.365726 240360.0 149579.0 \n", 1786 | "79500US0608103 0.753804 0.495312 -0.258492 148930.0 104728.0 \n", 1787 | "79500US0608104 0.215766 0.516951 0.301185 232493.0 126807.0 \n", 1788 | "79500US0608105 0.116667 0.528668 0.412000 204539.0 136269.0 \n", 1789 | "79500US2503303 0.089206 0.481267 0.392061 115710.0 112634.0 \n", 1790 | "79500US2503304 0.539569 0.115997 -0.423573 117844.0 137728.0 \n", 1791 | "79500US3402301 0.511410 0.258935 -0.252474 200753.0 120590.0 \n", 1792 | "79500US3500200 0.213663 0.500233 0.286569 109167.0 98760.0 \n", 1793 | "79500US3500300 0.566291 0.284282 -0.282009 115416.0 123068.0 \n", 1794 | "79500US3603102 0.841614 0.553282 -0.288331 156857.0 149618.0 \n", 1795 | "79500US3700400 0.818956 0.609494 -0.209462 223526.0 120185.0 \n", 1796 | "79500US4802308 0.157603 0.412300 0.254696 179311.0 105889.0 \n", 1797 | "79500US4802313 0.342277 0.564901 0.222624 130403.0 116870.0 \n", 1798 | "79500US4802502 0.226250 0.457684 0.231434 116455.0 127022.0 \n", 1799 | "79500US4802504 0.525767 0.309175 -0.216592 226857.0 104588.0 \n", 1800 | "79500US4802507 0.735555 0.504637 -0.230918 156369.0 125627.0 \n", 1801 | "79500US4803400 0.386969 0.699929 0.312959 95160.0 179294.0 \n", 1802 | "79500US4805303 0.515004 0.265493 -0.249511 198111.0 144000.0 \n", 1803 | "97000US4830390 0.511651 0.298632 -0.213019 155778.0 172483.0 " 1804 | ] 1805 | }, 1806 | "execution_count": 11, 1807 | "metadata": {}, 1808 | "output_type": "execute_result" 1809 | } 1810 | ], 1811 | "source": [ 1812 | "race[race['white_chg'].abs() > 0.2][['name','white_07','white_14','white_chg','total_07', 'total_14']]" 1813 | ] 1814 | } 1815 | ], 1816 | "metadata": { 1817 | "kernelspec": { 1818 | "display_name": "Python 3", 1819 | "language": "python", 1820 | "name": "python3" 1821 | }, 1822 | "language_info": { 1823 | "codemirror_mode": { 1824 | "name": "ipython", 1825 | "version": 3 1826 | }, 1827 | "file_extension": ".py", 1828 | "mimetype": "text/x-python", 1829 | "name": "python", 1830 | "nbconvert_exporter": "python", 1831 | "pygments_lexer": "ipython3", 1832 | "version": "3.4.3" 1833 | } 1834 | }, 1835 | "nbformat": 4, 1836 | "nbformat_minor": 1 1837 | } 1838 | --------------------------------------------------------------------------------