2015-03-31 16 views
6

OK, sono a metà dell'intelligenza. Sto geocoding un dataframe con geopy. Ho scritto una semplice funzione per prendere un input - nome del paese - e restituire la latitudine e la longitudine. Io uso apply per eseguire la funzione e restituisce un oggetto serie Pandas. Non riesco a convertirlo in un dataframe. Sono sicuro che mi manca qualcosa di ovvio, ma sono nuovo in Python e ancora in RTFMing. A proposito, la funzione geocoder funziona alla grande.Python Panda 'applica' ritorna serie; non posso convertire in dataframe

# 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 

Ho anche provato

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

ottengo un singolo dataframe senza indice e un singolo colume con la serie in esso.

ho provato un certo numero di altri metodi, tra cui '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) 

che restituito un errore dopo un lungo periodo di tempo:

ValueError: Columns must be same length as key

Ho anche provato a convertire manualmente serie su un dataframe utilizzando il metodo df.from_dict(df_geo_in) senza successo.

L'obiettivo è di geocodificare 166 paesi univoci, quindi collegarli agli indirizzi 188K in df_addr. Sto cercando di essere pandas-y nel mio codice e non scrivere loop se possibile. Ma non ho trovato la magia per convertire serie in dataframes e questa è la prima volta che ho provato a usare apply.

Grazie in anticipo - antica C programmatore

+0

cosa dice type (df_geo_in) in diversi punti? è un dataframe? o una serie? in ogni caso potresti voler df_geo_in.fromdict() ?? df non ha significato se non lo hai definito .. Potresti aver bisogno di pd.DataFrame (df_geo_in) – dartdog

risposta

7

sto supponendo che df_geo è un df con una sola colonna in modo credo che il seguente dovrebbe funzionare:

cambiamento:

return lat, lon 

a

return pd.Series([lat, lon]) 

poi dovresti essere in grado di assegnare in questo modo:

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

cosa si è tentato di fare era assegnare il risultato di applymap a 2 nuove colonne che non è corretto qui come applymap è progettato per funzionare su ogni elemento in un df così a meno che i LHS ha la stessa forma atteso questo non darà il risultato desiderato

Anche il secondo metodo è errato perché si trascinano i paesi duplicati e ci si aspetta che questo assegni la geolocalizzazione di ogni paese, ma la forma è diversa.

E 'probabilmente più veloce per df grandi di per creare le geolocalizzazione non duplicati df di e quindi unire questo nuovo al vostro grande df in questo modo:

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

questo creerà un df con i paesi non duplicati con geo localizzazione indirizzi e quindi eseguiamo un'unione sinistra di nuovo al master df.

+0

Grazie! Questo l'ha risolto! Ora ho solo bisogno di capire meglio perché. – Harvey

0

sempre più facile da provare con alcuni dati di esempio, ma vi prego di provare la seguente funzione zip per vedere se funziona.

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