Я делаю тройной цикл за цикл данных с почти 70 тысячами записей. Как мне это оптимизировать?
Моя конечная цель - создать новую колонку со страной сейсмического события. У меня есть столбец широты, долготы и "места" (например: "17 км к северу от Северной Ненаны, Аляска"). Я попытался изменить геокодирование, но с 68 488 записями нет бесплатного сервиса, который бы позволял мне это делать. И как студент я не могу себе этого позволить.
Поэтому для сравнения со значениями USGS ['place'] я использую фрейм данных со списком стран и фрейм данных со списком штатов. Для этого я в конечном итоге остановился на использовании 3 для циклов.
Как вы можете предположить, это занимает много времени. Я надеялся, что есть способ ускорить процесс. Я использую Python, но я также использую r. Циклы for работают лучше на python.
Любые лучшие варианты я возьму.
USGS = pd.DataFrame(data = {'latitide':[64.7385, 61.116], 'longitude':[-149.136, -138.655], 'place':['17km N of North Nenana, Alaska', '74km WNW of Haines Junction, Canada'], 'country':[NA, NA]})
states = pd.DataFrame(data = {'state':['AK', 'AL'], 'name':['Alaska', 'Alabama']})
countries = pd.DataFrame(data = {'country':['Afghanistan', 'Canada']})
for head in states:
for state in states[head]:
for p in USGS['place']:
if state in p:
USGS['country'] = USGS['country'].map({p : 'United 'States'})
# I have not finished the code for the countries dataframe
У вас есть варианты для геокодирования. Mapquest предлагает бесплатные 15 000 звонков в месяц. Вы также можете посмотреть на использование geopy, что я и использую.
import pandas as pd
import geopy
from geopy.geocoders import Nominatim
USGS_df = pd.DataFrame(data = {'latitude':[64.7385, 61.116], 'longitude':[-149.136, -138.655], 'place':['17km N of North Nenana, Alaska', '74km WNW of Haines Junction, Canada'], 'country':[None, None]})
geopy.geocoders.options.default_user_agent = "locations-application"
geolocator=Nominatim(timeout=10)
for i, row in USGS_df.iterrows():
try:
lat = row['latitude']
lon = row['longitude']
location = geolocator.reverse('%s, %s' %(lat, lon))
country = location.raw['address']['country']
print ('Found: ' + location.address)
USGS_df.loc[i, 'country'] = country
except:
print ('Location not identified: %s, %s' %(lat, lon))
Входные данные :
print (USGS_df)
latitude longitude place country
0 64.7385 -149.136 17km N of North Nenana, Alaska None
1 61.1160 -138.655 74km WNW of Haines Junction, Canada None
Выход:
print (USGS_df)
latitude longitude place country
0 64.7385 -149.136 17km N of North Nenana, Alaska USA
1 61.1160 -138.655 74km WNW of Haines Junction, Canada Canada
Как насчет этого, используя zip():
for head in states:
for state, place in zip(states[head], USGS['place']):
if state in p:
USGS['country'] = USGS['country'].map({p : 'United States'})
Некоторое время:
Ваш метод
%%timeit
for head in states:
for state in states[head]:
for p in USGS['place']:
if state in p:
USGS['country'] = USGS['country'].map({p : 'United States'})
616 µs ± 7.22 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
Мое предложение:
%%timeit
for head in states:
for state, place in zip(states[head], USGS['place']):
if state in place:
USGS['country'] = USGS['country'].map({p : 'United States'})
47.9 µs ± 647 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
states
соcountries
? Не похоже , как вы используете этиcountries
dataframe где - нибудь в вашей логике.