【问题标题】:Python Pandas GeopyAttributeError: 'NoneType' object has no attribute 'latitude'Python Pandas GeopyAttributeError:“NoneType”对象没有属性“纬度”
【发布时间】:2018-11-05 23:43:35
【问题描述】:

我在网上到处寻找解决方案,但在任何地方都找不到。我正在从 CSV 文件中读取地址并进行地理编码并将两个新列写入新的 CSV。这适用于我选择的小样本量,但似乎我的 API 无法获取某些地址的经度和纬度值,从而导致错误。这是我的代码:

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'

即使脚本无法获取某些地址的纬度或经度,我仍然希望脚本执行其功能,我该如何忽略它?

【问题讨论】:

  • 问题是什么?如何不出现该错误?在这种情况下,您可能需要检查 x 是否为 None 而不是 x.latitude x.longitude 是否为 None。希望对您有所帮助。
  • 请编辑您的帖子以包含错误的完整追溯的副本!
  • 是的,我只是想知道如何忽略错误并继续执行脚本,我没有检查 x 是否为无吗?这就是我在我认为的两个功能中所做的。 @datapug
  • @seatal 在您检查的代码中是 x.latitude 是 None 但如果 x 是 None 则不是,它们是两个不同的东西。尝试用 x is None 和 x.longitude is None 替换 x.latitude is None 和 x is None

标签: python pandas csv geocode geopy


【解决方案1】:

具有“无”作为值的属性与根本不存在的属性之间存在差异。这类似于未定义的变量:当未定义 my_variable 而不是返回 False 时,下面的代码将失败:

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

要检查对象是否具有名称经度属性,您可以使用:

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

为了在您的代码中看到这种行为,您可以像这样更改函数 get_longitude/get_latitude:

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

【讨论】:

  • 好的,谢谢,如果我仍然希望脚本继续执行,即使对于某些地址它无法获得经度或纬度,我将如何执行此操作?
  • 我刚刚更新了我的答案,以包括我个人修改该代码的方式
  • 感谢您的帮助,完美运行! +1 @jfbeltran
【解决方案2】:

这里的问题是你想从 None 对象中获取“纬度”和“经度”。基本上是在做None.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



           

我遇到了同样的问题,这就是我能够解决的方法

【讨论】:

  • #sammyhawkrad 你能解释一下如何更改脚本以免出现此错误:“值的长度 (52) 与索引的长度 (40) 不匹配”
  • @RitaM 我有点失落。在我看来,您从您拥有的附加代码中得到错误,而不是从我在这里共享的脚本中得到错误。您可以分享您的完整代码,以便我看看是否可以提供帮助。
  • 我解决了这个问题。我不是你的剧本。对不起:)
【解决方案3】:

jfbeltran 关于 None 的值和对象实例的不存在属性之间的区别是正确的。 geopy 的地理编码方法return None 用于尚未找到的位置。

这是,IMO,一个更好的方法来解决你的问题,不需要定义自己的函数:

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'))

对于 geopy,您可能会发现 Usage with pandas 文档部分很有帮助:https://geopy.readthedocs.io/en/stable/#usage-with-pandas

【讨论】:

    【解决方案4】:

    要从具有地址的列中获取坐标,这也可以正常工作:

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

    【讨论】:

      猜你喜欢
      • 2018-06-21
      • 2013-04-19
      • 2019-10-03
      • 2021-01-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多