Take in incomplete user input street addresses, clean it, segregate based on word count and run it into Google maps places api and output completed & standardised addresses based on Json object retrieved.
Looking for specific input on:
- Does this code work fine at your end (as it works at mine)- i.e., does it do what it should? (it works fine at my end but I'm apprehensive)
- Can it be made more efficient in terms of space, time & computing required?
- Are there alternate ways to handle this task (street address classification, auto-completion and standardisation)?
FYI, I coded this on my Jupyter Notebook, where it works as intended.
# coding: utf-8
import pandas as pd
import numpy as np
import re
import googlemaps
gmaps = googlemaps.Client(key='AIzaSyDNF4JxWbuqnYNik2Np4XIpfAU8eOaY0Fg')
data = pd.read_csv('test_address_(clean).txt')
pd.set_option('display.max_colwidth', -1)
data.set_index(['ID'],inplace=True)
data.head()
#CLEAN THIS DATA
#REPLACE . WITH ,
#COMMA FOLLOWED BY 1 SPACE AND PRECEDED BY NON
#REMOVE DOUBLE SPACE
def subDot(Str):
return re.sub("[.]",", ",Str)
data['Address']=data['Address'].apply(subDot)
data.head()
data['Address'] = data['Address'].str.strip()
data['Address'] = data['Address'].str.replace(' ,',', ')
data['Address'] = data['Address'].str.replace(',',', ')
data['Address'] = data['Address'].str.replace(' ',' ')
data.head() #clean data
#check word count for guiding our segmentation
data['wordcount']=data['Address'].str.split(" ").apply(len)
data.head()
#Check unresolvable addresses
unresolvable_address=data[data['Resolvable']==0]
unresolvable_address.info()
unresolvable_address.head(20)
#we see that most of these addresses are 1 or 2 words long
#lets see how many data points in total are too short
data[data['wordcount']<3].info()
data[data['wordcount']<2].info()
data[data['wordcount']<3]['Resolvable'].sum()
data[data['wordcount']<2]['Resolvable'].sum()
#Ok there are 44 data points of 1 or 2 words in length, with 28 of them resolvable and 16 not.
#And there are 21 data points of 1 word length, with 10 of them resolvable and 11 not.
#If we include 2 word length data points, we will be introducing 15 unresolvable data points
#to minimize False Positive, It's better to not try to predict values for unresolvable data points
#So, lets not predict for these data points: 2 words or shorter
Long_address=data[data['wordcount']>2]
Long_address.info()
Long_address.head()
Long_address['Resolvable'].sum()
data['Pincode']=None
data['City']=None
data['Area']=None
data['locality']=None
data['Hnbr']=None
data['Full_Address']=None
data.head()
#Lets use our Google Maps Places API to standardize these addresses
def whereThisPlaceAtPin(Str):
try:
r = gmaps.geocode(Str)
for item in r[0]["address_components"]:
if item['types'][0] == 'postal_code':
return item['long_name']
except:
return None
def whereThisPlaceAtCity(Str):
try:
r = gmaps.geocode(Str)
for item in r[0]["address_components"]:
if item['types'][0] == 'administrative_area_level_1':
return item['long_name']
except:
return None
def whereThisPlaceAtArea(Str):
try:
r = gmaps.geocode(Str)
for item in r[0]["address_components"]:
if item['types'][0] == 'locality':
return item['long_name']
except:
return None
def whereThisPlaceAtlocality(Str):
try:
r = gmaps.geocode(Str)
for item in r[0]["address_components"]:
if item['types'][0] == 'political':
return item['long_name']
except:
return None
def whereThisPlaceAtHnbr(Str):
try:
r = gmaps.geocode(Str)
return r[0]["address_components"][0]['long_name']
except:
return None
def whereThisPlaceAtAddress(Str):
try:
r = gmaps.geocode(Str)
return r[0]["formatted_address"]
except:
return None
data['Pincode']=data['Address'].apply(whereThisPlaceAtPin)
data['City']=data['Address'].apply(whereThisPlaceAtCity)
data['Area']=data['Address'].apply(whereThisPlaceAtArea)
data['locality']=data['Address'].apply(whereThisPlaceAtlocality)
data['Hnbr']=data['Address'].apply(whereThisPlaceAtHnbr)
data['Full_Address']=data['Address'].apply(whereThisPlaceAtAddress)
data.head()
data[data['wordcount']>2].loc['Pincode'] = None
data[data['wordcount']>2].loc['City'] = None
data.to_csv("Checkpoint_final.csv")