A reverse address lookup uses the longitude and latitude to find the address.
Let’s say you have a DataFrame full of longitudes and latitudes and need to get the address information associated with each. Here’s an example:
df = pd.DataFrame([[38.8976763,-77.0387185],[40.7484405,-73.9878531],[48.8606111,2.337644]], columns=['latitude', 'longitude']) df
To convert those to an address, we can use geopy
Python package and the Google Maps API. To get started, you’ll need to sign up for a Google Cloud account and request an API key. It’s free to sign up for the Google Cloud Platform. They have a pretty generous free tier, however, If you are trying to convert a lot of addresses, I would look into pricing. Here is what you’ll need to do to get started:
- Get an API key from Google. Follow these instructions.
- Enable the Geocoding API. You can simply search for it using the top menu search bar in the Google Cloud Console.
Now you are all set to return back to Python. You’ll import the following libraries and insert your API key.
import geopandas as gpd import geopy from geopy.geocoders import GoogleV3 geolocator = GoogleV3(api_key='')
To test it out, get input the longitude and latitude, run the geolocator.reverse
function, then view the entire details of the address using address.raw
. Here is an example using the latitude and longitude of the Empire State Building that I got from Google Maps. The longitude and latitude are in the address bar of your google maps search result.
point = [40.7483811,-73.9898062] address = geolocator.reverse(point,exactly_one=True) address.raw
If successful, you’ll get a bunch of JSON data with the results! The next step is to convert this to a function and append the data to your DataFrame. To isolate the long_name
from the data, use the following code:
pd.json_normalize(address.raw['address_components']).explode(column='types').drop_duplicates(subset=['types']).set_index('types')['long_name']
Breaking this Down
Let’s take a closer look at each component of the previous code.
Convert the Data to a DataFrame
Using pd.json_normalize
we can easily convert the data to a DataFrame. However, you’ll notice that the types column is a list.
convert_to_json = pd.json_normalize(address.raw['address_components']) convert_to_json
Break up the types
Column
To break up the types
column, you can use explode(column='types')
which breaks up the list and creates a new row for each list item.
expand_types = convert_to_json.explode(column='types') expand_types
Drop Duplicates
Next, you’ll notice that the types
column has a few duplicates like political and locality. We can remove them using drop_duplicates()
.
drop_duplicates = expand_types.drop_duplicates(subset=['types']) drop_duplicates
Set Index and Isolate the Long Name
Finally, we can set the index as our types
column and isolate the long_name
column to return a series.
set_index_and_isolate_long_name = drop_duplicates.set_index('types')['long_name'] set_index_and_isolate_long_name
Writing a Pandas Function
Here is how you can make this into a Pandas function so that you can apply to a DataFrame.
def get_adress(x): ''' Takes in latitude and longitude and returns and address using the Google API ''' point = [x.latitude,x.longitude] address = geolocator.reverse(point,exactly_one=True) try: address = geolocator.reverse(point,exactly_one=True) return pd.json_normalize(address.raw['address_components']).explode(column='types').drop_duplicates(subset=['types']).set_index('types')['long_name'] except: pass
Using Nominatim
Using the Google Maps API is very accurate and returns a lot of great information. The caveat is that you do have to pay for the service after a certain limit. A free way of doing a reverse address lookup is to use geopy with Nominatim. Here is an example of how you would do a reverse address lookup using it.
First let’s import the packages:
from geopy.geocoders import Nominatim from geopy.extra.rate_limiter import RateLimiter import pandas as pd locator = Nominatim(user_agent="myGeocoder")
Next, we will create a function that takes a DataFrame as the argument.
def get_adress(x): ''' Takes in latitude and longitude and returns and address using the Google API ''' coordinates = [x.latitude,x.longitude] location = locator.reverse(coordinates) address = location.raw address_converted = pd.json_normalize(address).squeeze() #squeeze converts a dataframe to a pandas series return address_converted
Now we can apply the function to the test DataFrame we made at the beginning of the post:
df.apply(get_adress ,axis=1)
Lastly, you can merge this address data back to the original DataFrame by running pd.concat([df,addresses_df], axis=1)
Final Thoughts
Check out more Python tricks in this Colab Notebook or in my recent Python Posts.
Thanks for reading!