Python Pandas "apply" возвращает серию; не удается преобразовать в dataframe

ладно,я в тупике. Я геокодировании таблицы данных с geopy. Я написал простую функцию для ввода-название страны-и возврата широты и долготы. Я использую apply для запуска функции, и она возвращает объект серии Pandas. Я не могу преобразовать его в dataframe. Я уверен, что пропустил что-то очевидное, но я новичок в python и все еще RTFMing. Кстати, функция геокодера отлично работает.

# Import libraries 
import os 
import pandas as pd 
import numpy as np
from geopy.geocoders import Nominatim

def locate(x):
    geolocator = Nominatim()
    # print(x) # debug
    try:
        #Get geocode
        location = geolocator.geocode(x, timeout=8, exactly_one=True)
        lat = location.latitude
        lon = location.longitude
    except:
        #didn't work for some reason that I really don't care about
        lat = np.nan
        lon = np.nan
   #  print(lat,lon) #debug
    return lat,  lon # Note: also tried return { 'LAT': lat, 'LON': lon }

df_geo_in = df_addr.drop_duplicates(['COUNTRY']).reset_index()    #works perfectly
df_geo_in['LAT'], df_geo_in['LON']  = df_geo_in.applymap(locate) 
# error: returns more than 2 values - default index + column with results

Я тоже пробовал

df_geo_in['LAT','LON'] = df_geo_in.applymap(locate)

Я получаю один dataframe без индекса и одного colume с серией в нем.

Я пробовал ряд других методов, включая 'applymap' :

source_cols = ['LAT','LON'] 
new_cols = [str(x) for x in source_cols]

df_geo_in = df_addr.drop_duplicates(['COUNTRY']).set_index(['COUNTRY']) 
df_geo_in[new_cols] = df_geo_in.applymap(locate)

который вернул ошибку через долгое время:

ValueError: столбцы должны быть одинаковой длины с ключом

Я также попытался вручную преобразовать серию в фрейм данных, используя df.from_dict(df_geo_in) метод без успеха.

цель состоит в том, чтобы геокодировать 166 уникальных стран, а затем присоединиться он возвращается к адресам 188K в df_addr. Я пытаюсь быть пандами в своем коде и не писать циклы, если это возможно. Но я не нашел магии для преобразования серий в фреймы данных, и это первый раз, когда я попытался использовать apply.

заранее спасибо-ancient c programmer

2 ответов


Я предполагаю, что df_geo является df с одним столбцом, поэтому я считаю, что должно работать следующее:

изменения:

return lat,  lon

to

return pd.Series([lat,  lon])

тогда вы должны иметь возможность назначить так:

df_geo_in[['LAT', 'LON']] = df_geo_in.apply(locate)

то, что вы пытались сделать, это назначить результат applymap до 2 новых столбцов, которые неверны здесь как applymap предназначен для работы с каждым элементом в df, поэтому, если lhs не имеет той же ожидаемой формы, это не даст желаемого результат.

ваш последний метод также неверен, потому что вы отбрасываете дубликаты стран, а затем ожидаете, что это назначит геолокацию каждой страны, но форма отличается.

вероятно, для больших df быстрее создать геолокацию, не дублирующуюся df, а затем объединить это обратно в ваш большой df, например:

geo_lookup = df_addr.drop_duplicates(['COUNTRY'])
geo_lookup[['LAT','LNG']] = geo_lookup['COUNTRY'].apply(locate)
df_geo_in.merge(geo_lookup, left_on='COUNTRY', right_on='COUNTRY', how='left')

это создаст df с не дублированными странами с адресами геолокации, а затем мы выполним левое слияние обратно в мастер-ДФ.


всегда легче протестировать с некоторыми образцами данных, но, пожалуйста, попробуйте следующую функцию zip, чтобы увидеть, если он работает.

df_geo_in['LAT_LON'] = df_geo_in.applymap(locate) 
df_geo_in['LAT'], df_geo_in['LON'] = zip(*df_geo_in.LAT_LON)