Reputation: 73
I'm trying to run a very simple geopy reverse script that takes a lat-long coordinate and returns specifically the country, state and city. All three of these are easily pulled from the JSON response object. However, when I try to extract the 'city' feature, I get a KeyError. If I double check to see if 'city' is in the response object, it definitely is (see below), so what exactly is going on? I can extract country and state without issue, why not the city? I've also noticed this happening for district and borough.
This is my code:
df = pd.read_csv('data.csv')
geolocator = Nominatim(user_agent='latlongconvert')
df['address'] = df['LastMatchingLatLong'].apply(geolocator.reverse)
df['country'] = df['address'].apply(lambda x: (x.raw['address']['country']))
df['state'] = df['address'].apply(lambda x: (x.raw['address']['state']))
df['city'] = df['address'].apply(lambda x: (x.raw['address']['city']))
Where the last line creates the following error: KeyError: 'city'
When I look at a particular row it clearly contains the city key:
df['address'][0].raw['address']
Ouput:
{'tourism': 'Schwanentempel',
'road': 'Auedamm',
'suburb': 'Südstadt',
'city': 'Kassel',
'municipality': 'Niestetal',
'state': 'Hessen',
'postcode': '34121',
'country': 'Deutschland',
'country_code': 'de'}
I can even use df['address'][0].raw['address']['city']
to extract it for that particular row.
Upvotes: 1
Views: 906
Reputation: 73
For anyone else having this issue, Geopy does not always return city, borough, district, etc. so using a lambda function without accounting for missing values will give you a keyerror.
The following code sorted this issue out for me:
df['country'] = df['address'].apply(lambda x: (x.raw['address']['country']))
df['state'] = df['address'].apply(lambda x: (x.raw['address']['state']))
df['city'] = df['address'].apply(lambda x: (x.raw['address']['city'] if 'city' in x.raw['address'].keys() else None ))
Upvotes: 2