У меня есть список примерно 400 тыс. IP (хранится в pandas DataFrame df_IP) для геолокации с использованием базы данных maxming geoIP. Я использую версию City, и я извлекаю город, длину волны, долготу и код графства (департамент во Франции), потому что некоторые города имеют одно и то же имя, но находятся в самых разных местах.Ускорьте данные. Loc()
Вот мой рабочий код:
import geoip2.database
import pandas as pd
reader = geoip2.database.Reader('path/to/GeoLite2-City.mmdb')
results = pd.DataFrame(columns=('IP',
'city',
'latitude',
'longitude',
'dept_code'))
for i, IP in enumerate(df_IP["IP"]):
try :
response = reader.city(IP)
results.loc[i] = [IP,response.city.name,response.location.latitude,response.location.longitude,response.subdivisions.most_specific.iso_code]
except Exception as e:
print ("error with line {}, IP {}: {}").format(i,df_IP["IP"][i],e)
Он хорошо работает, но она становится все медленнее и медленнее на каждом цикле. Если я нахожу это на 1000 первых IP, я беру 4.7s, поэтому весь 400k займет около 30 минут, но он работает почти 4 часа.
Единственное, что может замедлить со временем IMO, это заполнение Dataframe results
: какие у меня альтернативы, которые не используют .loc
и могут быть быстрее? В конце концов, мне все равно нужен один и тот же файл.
Мне также будет интересно узнать, почему loc
настолько медленный на больших кадрах данных.
вы не задумывались об использовании одного из pandas' итераторов (например, 'iterrows()') перебрать ваши строки и использовать 'применить 'с помощью функции вашего читателя создать один новый столбец со строкой, в которой есть все ваши геоданные? Затем вы можете разбить строки для создания отдельных столбцов для всех ваших геоданных. Не уверен, что это будет быстрее, но при итерации над фреймворком данных обычно лучше использовать что-то вроде 'iterrows()'. – Khris
У меня была аналогичная проблема в прошлом, когда 'loc' был очень медленным, когда в цикле for. Я обнаружил, что могу обойти проблему, создав данные для нового столбца в виде отдельного списка, а затем переназначаю его в этой форме. Это потребовало большего количества строк кода и было немного уродливым, но имело гораздо лучшую производительность, чем 'loc'. Возможно, стоит подумать, можете ли вы применить это. – oliversm
@oliversm вы можете уточнить? Я не понимаю вашего трюка. – CoMartel