# default_exp liquor
This colab and more can be found at https://github.com/BNIA/vitalsigns.
Whats Inside?:
The Guided Walkthrough
This notebook was made to create the following Housing Vital Signs Indicators:
https://bniajfi.org/indicators/Children%20And%20Family%20Health/liquor
This indicator reflects the number of business establishments that possess a Class A (Off Sale package goods no on-premises consumption - 6 days, 6:00 a.m.- Midnight. No Sunday sales except Sundays between Thanksgiving Day and New Year's Day upon issuance of a special license for each Sunday) or BD7 (tavern) business license that allows them to sell beer, wine, or liquor. Other liquor licenses to restaurants or on-premise consumption were not included in this analysis. This number is provided by 1,000 residents to allow for comparison across neighborhoods.
Indicators Used
- ✅ 109 - Liquor - (Liquor) Liquor Outlet Density (per 1,000 Residents)
Datasets Used
- ✅ Liquor.Liquor_201X (109-columns)
❌
year = '19'
Guided Walkthrough
SETUP Enviornment:
Import Modules
! pip install -U -q PyDrive
! pip install geopy
! pip install geopandas
! pip install geoplot
! pip install dataplay
! pip install matplotlib
! pip install psycopg2-binary! apt-get install build-dep python-psycopg2
! apt-get install libpq-dev
! apt-get install libspatialindex-dev!pip install rtree
!pip install dexplotfrom dataplay.geoms import workWithGeometryData%%capture
# These imports will handle everything
import os
import sys
import csv
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import geopandas as gpd
from geopandas import GeoDataFrame
import psycopg2
import pyproj
from pyproj import Proj, transform
# conda install -c conda-forge proj4
from shapely.geometry import Point
from shapely import wkb
from shapely.wkt import loads
# https://pypi.org/project/geopy/
from geopy.geocoders import Nominatim
# In case file is KML, enable support
import fiona
fiona.drvsupport.supported_drivers['kml'] = 'rw'
fiona.drvsupport.supported_drivers['KML'] = 'rw'from IPython.display import clear_output
clear_output(wait=True)import ipywidgets as widgets
from ipywidgets import interact, interact_manual
Configure Enviornment
# This will just beautify the output
pd.set_option('display.expand_frame_repr', False)
pd.set_option('display.precision', 2)
from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = "all"
# pd.set_option('display.expand_frame_repr', False)
# pd.set_option('display.precision', 2)
# pd.reset_option('max_colwidth')
pd.set_option('max_colwidth', 20)
# pd.reset_option('max_colwidth')
Prep Datasets
TPOP CSA and Baltimore
Get Baltimore
Click to toggle
csa = "https://services1.arcgis.com/mVFRs7NF4iFitgbY/ArcGIS/rest/services/Tpop/FeatureServer/0/query?where=1%3D1&outFields=*&returnGeometry=true&f=pgeojson"
csa = gpd.read_file(csa);
csa.head(1) Get CSA
url2 = "https://services1.arcgis.com/mVFRs7NF4iFitgbY/ArcGIS/rest/services/Tpop/FeatureServer/1/query?where=1%3D1&outFields=*&returnGeometry=true&f=pgeojson"
csa2 = gpd.read_file(url2);
csa2['CSA2010'] = csa2['City_1']
csa2['OBJECTID'] = 56
csa2 = csa2.drop(columns=['City_1'])
csa2.head()
Append do no append Bcity. We put it on the Bottom of the df because when performing the ponp it returns only the last matching columns CSA Label.
# csa = pd.concat([csa2, csa], ignore_index=True)
csa = csa.append(csa2).reset_index(drop=True)csa.head(3)csa.tail(3)csa.drop(columns=['Shape__Area', 'Shape__Length', 'OBJECTID'], axis=1).to_file("BCity_and_CSA.geojson", driver='GeoJSON')
Liquor
import pandas as pd
import geopandas
original = gpd.read_file("Liquor_2020_CSACity_forVS19.shp", geometry='geometry');
original.columns original.rename(columns={ 'CSA':'CSA2010', 'BaltCity':'InBaltimore'}, inplace=True)
df = original[ original['CSA2010'].notnull() | original['InBaltimore'].notnull() ]print('After filtering records where a CSA or Baltimore geo-code match Exists')
print( 'All rows Before Filter: ', original.shape[0] ) # rows, columns
print( '# w BCity.isnull: ', df.InBaltimore.isnull().sum() ); bmorow = df[ df.CSA2010.isnull() ].shape[0]
print( '# w CSA2010.isnull: ', bmorow ); csarow = df[ df.CSA2010.notnull() ].shape[0]
print( '# w CSA2010.notnull: ', csarow );
print( '# rows After Filter: ', df.shape[0],'==',csarow,'+',bmorow,'==', csarow + bmorow); # add baltimore city
df.CSA2010 = df.CSA2010.fillna('Baltimore City')len(df[ (df['License'].str.contains('LA|LA-2|LAS|LBD7|WA|WAS', regex=True) ) ])len(df[ (df['License'].str.contains('LA', regex=True) ) ])len(df[ (df['License'].str.contains('LA-2', regex=True) ) ])len(df[ (df['License'].str.contains('LAS', regex=True) ) ])len(df[ (df['License'].str.contains('LBD7', regex=True) ) ])len(df[ (df['License'].str.contains('WA', regex=True) ) ])len(df[ (df['License'].str.contains('WAS', regex=True) ) ])liquordf = df.copy()
liquordf = liquordf[['CSA2010','InBaltimore', 'License']]
liquordf.head(1)
Indicator Liquor 109
#export
def liquor(df, csa, yr):
# Create the Numerator
liquor = df.copy()
liquor = liquor[
( liquor['License'].str.contains('LA|LA-2|LAS|LBD7|WA|WAS', regex=True) )
]
liquor['count'] = 1
liquor = liquor.groupby('CSA2010').sum(numeric_only=True)
# Make sure ALL csas and BaltimoreCity are included and sorted.
liquor = csa.merge( liquor, left_on='CSA2010', right_on='CSA2010', how='outer' )
liquor.drop( columns=['geometry', 'Shape__Length','Shape__Area'], inplace=True)
# Baltimoire has records not in the
liquor.at[55,'count']=liquor['count'].sum()
# Perform the calculation
liquor['109-liquor'+year] = liquor['count'] / liquor['tpop10'] * 1000
compareYears = gpd.read_file("https://services1.arcgis.com/mVFRs7NF4iFitgbY/ArcGIS/rest/services/Liquor/FeatureServer/0/query?where=1%3D1&outFields=*&returnGeometry=true&f=pgeojson");
prevYear = 'liquor'+ str( int(year) - 1 )
if prevYear in compareYears.columns:
liquor = liquor.merge( compareYears[['CSA2010', prevYear]], left_on='CSA2010', right_on='CSA2010', how='outer' )
liquor['change'] = liquor['109-liquor'+year] - liquor[ prevYear ]
liquor['percentChange'] = liquor['change' ] / liquor[ prevYear ] * 100
liquor['change'] = liquor['change'].apply(lambda x: "{:.2f}".format(x) )
print( 'Records Matching Query: ', liquor.size / len(liquor.columns) )
return liquor
fin = liquor(liquordf, csa, year)
fin.to_csv('109-liquor'+year+'.csv', index=False)
fin.head(60)