Геопи, панды, ДЛЯ сбоя цикла

#python-3.x #pandas #for-loop #geopy

Вопрос:

Я учусь сам geopy . Это кажется простым и понятным, но мой код не работает. Предполагается, что:

  • прочитайте в списке поля адреса из CSV в pandas df
  • объедините поля адресов в один столбец, отформатированный для geopy
  • составьте список из нового столбца
  • введите каждый элемент в списке geopy через цикл for и верните координаты добавьте координаты в исходный файл df и экспортируйте его в CSV
     #setup
    from geopy.geocoders import Nominatim
    import pandas as pd
        
    #create the df
    df = pd.DataFrame(pd.read_csv('properties to geocode.csv'))
    df['Location'] = df['Street Address'].astype(str) "," df['City'].astype(str) "," df['State'].astype(str)
        
    #create the geolocator object
    geolocator = Nominatim(timeout=1, user_agent = "My_Agent")
        
    #create the locations list
    locations = df['Location']
        
    #empty lists for later columns
    lats = []
    longs = []
        
    #process the location list
    for item in locations: 
        location = geolocator.geocode('item')
        lat =  location.latitude
        long = location.longitude
        lats.append(lat)
        longs.append(long)
        
    #add the lists to the df
    df.insert(5,'Latitude',lats)
    df.insert(6,'Longitude',longs)
        
    #export
    df.to_csv('geocoded-properties2.csv',index=False)
 

Что-то не работает, потому что оно возвращает одинаковые значения широты и долготы для каждой строки вместо уникальных координат для каждой.

Я нашел рабочий код с использованием .apply в другом месте, но мне интересно узнать, что я сделал не так. Есть какие-нибудь мысли?

Комментарии:

1. location = geolocator.geocode('item') вы передаете строковый литерал, а не значение элемента переменной

2. Спасибо за ваш ответ. когда я удаляю «»вокруг элемента, я получаю следующую ошибку: Ошибка атрибута: объект «Нетип» не имеет атрибута «широта»

3. Я дал более развернутый ответ. Если вы укажете адрес, который не найден geolocator.geocode() , возвращается None . Это явно проверяется в функции, которую я написал, прежде чем она вернется

Ответ №1:

  • ваш код не содержит примеров данных. Использовали некоторые примеры данных, доступных из общедоступных API, для демонстрации
  • ваш код передает литерал в geolocator.geocode() — это должен быть адрес, связанный со строкой
  • привели пример использования с пандами apply , понимание списка и for эквивалент цикла понимания
  • результаты показывают, что все три подхода эквивалентны
 from geopy.geocoders import Nominatim
import requests
import pandas as pd

searchendpoint = "https://directory.spineservices.nhs.uk/ORD/2-0-0/organisations"
# get all healthcare facilities in Herefordshire
dfhc = pd.concat([pd.json_normalize(requests
                             .get(searchendpoint, params={"PostCode":f"HR{i}","Status":"Active"})
                             .json()["Organisations"]) 
           for i in range(1,10)]).reset_index(drop=True)

def gps(url, geolocator=None):
    # get the address and construct a space delimted string
    a = " ".join(str(x) for x in requests.get(url).json()["Organisation"]["GeoLoc"]["Location"].values())
    lonlat = geolocator.geocode(a)
    if not lonlat is None:
        return lonlat[1]
    else:
        return (0,0)

# work with just GPs
dfgp = dfhc.loc[dfhc.PrimaryRoleId.isin(["RO180","RO96"])].head(5).copy()

geolocator = Nominatim(timeout=1, user_agent = "My_Agent")


# pandas apply
dfgp["lonlat_apply"] = dfgp["OrgLink"].apply(gps, geolocator=geolocator)

# list comprehension
lonlat = [gps(url, geolocator=geolocator) for url in dfgp["OrgLink"].values]
dfgp["lonlat_listcomp"] = lonlat

# old school loop
lonlat = []
for item in dfgp["OrgLink"].values:
    lonlat.append(gps(item, geolocator=geolocator))
dfgp["lonlat_oldschool"] = lonlat

 
Имя ОргИд Статус Класс оргрекордов почтовый индекс Дата последнего изменения Первичная роль Первичное описание OrgLink lonlat_apply lonlat_listcomp lonlat_oldschool
7 ОПЕРАЦИЯ НА ЭЙЛСТОУН-ХИЛЛ M81026002 Активный RC2 1 ЧАС 1 ЧАС 2020-03-19 РО96 ОТРАСЛЕВАЯ ХИРУРГИЯ https://directory.spineservices.nhs.uk/ORD/2-0-0/organisations/M81026002 (52.0612429, -2.7026047) (52.0612429, -2.7026047) (52.0612429, -2.7026047)
9 ШКОЛА БАРРС-КОРТ 5CN91 Активный RC2 HR1 1EQ 2021-01-28 RO180 САЙТ ДОВЕРИЯ ПЕРВИЧНОЙ МЕДИЦИНСКОЙ ПОМОЩИ https://directory.spineservices.nhs.uk/ORD/2-0-0/organisations/5CN91 (52.0619209, -2.7086105) (52.0619209, -2.7086105) (52.0619209, -2.7086105)
13 ОПЕРАЦИЯ В БОДЕНХЭМЕ 5CN24 Активный RC2 HR1 3JU 2013-05-08 RO180 САЙТ ДОВЕРИЯ ПЕРВИЧНОЙ МЕДИЦИНСКОЙ ПОМОЩИ https://directory.spineservices.nhs.uk/ORD/2-0-0/organisations/5CN24 (52.152405, -2.6671942) (52.152405, -2.6671942) (52.152405, -2.6671942)
22 АББАТСТВО БЕЛЬМОНТ 5CN16 Активный RC2 HR2 9RP 2013-05-08 RO180 САЙТ ДОВЕРИЯ ПЕРВИЧНОЙ МЕДИЦИНСКОЙ ПОМОЩИ https://directory.spineservices.nhs.uk/ORD/2-0-0/organisations/5CN16 (52.0423056, -2.7648698) (52.0423056, -2.7648698) (52.0423056, -2.7648698)
24 МЕДИЦИНСКИЙ ЦЕНТР БЕЛЬМОНТА 5CN22 Активный RC2 HR2 7XT 2013-05-08 RO180 САЙТ ДОВЕРИЯ ПЕРВИЧНОЙ МЕДИЦИНСКОЙ ПОМОЩИ https://directory.spineservices.nhs.uk/ORD/2-0-0/organisations/5CN22 (52.0407746, -2.739788) (52.0407746, -2.739788) (52.0407746, -2.739788)