0
votes

I'm trying to use Google's reverse geocoding API to get the city, state, and country for a list of 250 latitude and longitude coordinates. The pandas dataframe, df, contains the location coordinates in the column df['point']. I would like to add the city, state, and country as new columns to the original df. The python code below works perfectly for the state and country columns, but fails for the city column because the 'city_list' is two results short. I get this error:

ValueError: Length of values (248) does not match length of index (250)

I've been struggling to figure out how to fix this. Is there some way to add "error" to the list for the two rows that fail to produce cities? Many, many thanks for your help with this!!!

import googlemaps
import json
import pandas as pd

gmaps = googlemaps.Client(key='APIKEYHERE')

stored=[]
city_list=[]
state_list=[]
country_list=[]

for latlng in df['point']:
    r_geocode_result = gmaps.reverse_geocode((latlng))
    stored.append(r_geocode_result)
    address_components = r_geocode_result[0]['address_components']
    for address_type in address_components:
        flags = address_type.get('types', [])
        if 'locality' in flags:
            city = address_type['long_name']
            city_list.append(city)
        elif 'administrative_area_level_1' in flags:
            state = address_type['short_name']
            state_list.append(state)
        elif 'country' in flags and 'political' in flags:
            country = address_type['short_name']
            country_list.append(country)

# Convert lists into columns in original df
df['city'] = city_list
df['state'] = state_list
df['country'] = country_list
1

1 Answers

0
votes

Apparently one of the created lists is shorter than the dataframe. This can happen because you only have if conditions, but no else. So your code doesn't append anything if the if condition isn't met. As a solution you could lookup the values through list comprehension and assign None to the value if the list is empty. Also I suggest using pd.apply:

import googlemaps
import pandas as pd

gmaps = googlemaps.Client(key='APIKEYHERE')

def get_location(latlng):
    r_geocode_result = gmaps.reverse_geocode((latlng))
    address_components = r_geocode_result[0]['address_components']

    city = [i['long_name'] for i in address_components if 'locality' in i['types']]
    city = city[0] if city else None

    state = [i['long_name'] for i in address_components if 'administrative_area_level_1' in i['types']]
    state = state[0] if state else None

    country = [i['long_name'] for i in address_components if all(elem in ['country', 'political'] for elem in i['types'])]
    country = country[0] if country else None

    return pd.Series([city, state, country])

df[['city','state','country']] = df['point'].apply(get_location)