简体   繁体   中英

Python Pandas GeopyAttributeError: 'NoneType' object has no attribute 'latitude'

I've looked everywhere online trying to find a solution but I can't find one anywhere. I'm reading an address from a CSV file and geocoding and writing two new columns into a new CSV. This works with small sample sizes I've chosen, but it appears my API can't get the longitude and latitude values for some addresses thus causing an error. Here's my code:

import geopy
import pandas 
from geopy.geocoders import Bing


def main():
    io = pandas.read_csv('newoutput3.csv',index_col=None, header=0, 
    sep=",",encoding='cp1252')
    def get_latitude(x):
      if x.latitude is None:
         x.latitude = None
      else:
         return x.latitude


    def get_longitude(x):
      if x.longitude is None:
         x.longitude = None
      else:
         return x.longitude

    geolocator = Bing('myAPIkey',timeout=5)
    geolocate_column = io['ADDRESS'].apply(geolocator.geocode)
    io['latitude'] = geolocate_column.apply(get_latitude)
    io['longitude'] = geolocate_column.apply(get_longitude)
    io.to_csv('geocoding-output17.csv')   




if __name__ == '__main__':
    main()

File "C:/Users/Chris/Downloads/WPy-3662/scripts/geocoder.py", line 16, in 
get_latitude
   if x.latitude is None:

AttributeError: 'NoneType' object has no attribute 'latitude'

I still want the script to do what it does even if it can't get the latitude or longitude for certain addresses, how do i go about ignoring it?

There is a difference between an attribute having "None" as a value and the attribute not existing at all. This is analogous to an undefined variable: the code below fails when my_variable is not defined instead of returning False :

>>> my_variable == None
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'my_variable' is not defined 

To check if an object has an attribute of name longitude you can use:

# Returns True/False depending on whether x.longitude is an existing attribute
>>> hasattr(x, 'longitude')
False

In order to see this behavior in your code you could change the functions get_longitude/get_latitude like so:

def get_latitude(x):
  if hasattr(x,'latitude') and (x.latitude is not None): 
     return x.latitude


def get_longitude(x):
  if hasattr(x,'longitude') and (x.longitude is not None): 
     return x.longitude

jfbeltran is right about the difference between None for the value and non-existing attribute for an object instance. geopy's geocode methods return None for locations which haven't been found.

Here is, IMO, a nicer way to solve you problem which doesn't require defining own functions:

import operator

non_null_geolocate_column = geolocate_column[~geolocate_column.isnull()]
io['latitude'] = None
io['latitude'] = non_null_geolocate_column.apply(operator.attrgetter('latitude'))
io['longitude'] = None
io['longitude'] = non_null_geolocate_column.apply(operator.attrgetter('longitude'))

For geopy specifically, you may find the Usage with pandas documentation section helpful: https://geopy.readthedocs.io/en/stable/#usage-with-pandas

The problem here is that you are tring to get 'latitude' and 'longitude' from a None object. Basically doing None.latitude. So the best way to go about this is to first check if the geocoder returns a value before you try to access the 'longitude' and 'latitude'.

lat = []
long = []
for row in io['ADDRESS']:
    addr = geolocator.geocode(row, timeout=10)
    if addr is None:
        lat.append(None)
        long.append(None)
    else:
        latitude = ad.latitude
        longitude = ad.longitude  
    
    lat.append(latitude)
    long.append(longitude)

io['latitude'] = lat
io['longitude'] = long



           

I faced the same issue you have and this was how I was able to resolve it

To get coordinates from a column with address this also works just fine:

df.column.apply
(
lambda x: geolocator.geocode(x).latitude if geolocator.geocode(x) != None else 'NF'
)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM