How to create a spreadsheet converting or cross walking old Election Districts to new Election districts
How to create a spreadsheet converting or crosswalking old Election Districts to new Election districts
It turns out with Python and GeoPANDAS available on pip it’s pretty easy to create a Microsoft Excel-style Spreadsheet with new election districts with the percentage of the old election districts within them. This code can also be used to calculate the percentage of a county in a Senate district. Obviously, you will need to update all of the paths and field names for your Shapefiles.
# requires the geopandas and pandas python libraries, available from pip
import pandas as pd
import geopandas as gpd
# Load Old EDs etc Shapefile
ac11 = gpd.read_file(r'/home/andy/Documents/GIS.Data/election.districts/2011albanyEDs.shp').to_crs(epsg='3857')
# Load the New EDs etc Shapefile
ac20 = gpd.read_file(r'/home/andy/Albany County October 2020 ED.gpkg').to_crs(epsg='3857')
# Save the area of new EDs
ac20['ed20_area']=ac20.area
# Create a GIS intersection of old and new EDs
edover=gpd.overlay(ac11, ac20, how='intersection')
# Calculate percentage of the New ED covered by the Old ED
edover['Percent of 2020 ED Area Covered by 2011 ED']=edover.area/edover['ed20_area']*100
# Rename columns to something more sensible
edover=edover.rename({'NAME_1':'2011 ED','NAME_2':'2020 ED'},axis=1)
# Exclude Portions of Old EDs that are less then 1% of New EDs
# Sort and Group by New ED and then Percentage of the Old ED
edover[(edover['Percent of 2020 ED Area Covered by 2011 ED']>1)][['2011 ED','2020 ED','Percent of 2020 ED Area Covered by 2011 ED']].sort_values(by=['2020 ED','Percent of 2020 ED Area Covered by 2011 ED']).groupby(by=['2020 ED','2011 ED']).median().to_excel('/tmp/New to Old Election District Crosswalk.xlsx')
Here is a sample of the Microsoft Excel-style spreadsheet that will be exported.
2020 ED | 2011 ED | Percent of 2020 ED Area Covered by 2011 ED |
Albany Ward 1 Dist 1 | Albany 1-1 | 51.98 |
Albany 8-4 | 47.97 | |
Albany Ward 1 Dist 10 | Albany 2-7 | 100.00 |
Albany Ward 1 Dist 2 | Albany 7-4 | 99.64 |
Albany Ward 1 Dist 3 | Albany 1-1 | 53.42 |
Albany 1-2 | 46.35 | |
Albany Ward 1 Dist 4 | Albany 1-3 | 46.06 |
Albany 1-4 | 53.77 | |
Albany Ward 1 Dist 5 | Albany 1-1 | 100.00 |
Albany Ward 1 Dist 6 | Albany 1-5 | 96.07 |
Albany 2-2 | 3.72 | |
Albany Ward 1 Dist 7 | Albany 1-1 | 28.87 |
Albany 2-10 | 34.49 | |
Albany 2-8 | 36.52 | |
Albany Ward 1 Dist 8 | Albany 1-5 | 12.52 |
Albany 1-6 | 30.09 | |
Albany 2-2 | 24.88 | |
Albany 2-7 | 32.51 | |
Albany Ward 1 Dist 9 | Albany 1-4 | 92.60 |
Albany 1-5 | 7.09 | |
Albany Ward 10 Dist 1 | Albany 10-2 | 99.30 |
Albany Ward 10 Dist 2 | Albany 10-8 | 99.69 |
Albany Ward 10 Dist 3 | Albany 10-1 | 99.64 |
Albany Ward 10 Dist 4 | Albany 10-4 | 99.57 |
Albany Ward 10 Dist 5 | Albany 10-5 | 99.44 |
Albany Ward 10 Dist 6 | Albany 10-5 | 68.17 |
Albany 10-8 | 31.83 | |
Albany Ward 10 Dist 7 | Albany 10-8 | 48.18 |
Albany 11-5 | 13.05 | |
Albany 11-7 | 38.66 | |
Albany Ward 10 Dist 8 | Albany 11-7 | 32.47 |
Albany 6-1 | 67.24 |