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)