我有一個約400k IP(存儲在pandas DataFrame df_IP中)的列表,使用最大化geoIP數據庫進行地理定位。我使用城市版本,並且我檢索城市,經度和城市代碼(在法國出發),因爲一些城市的名稱相同但位置卻非常不同。加速數據幀.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.7秒,所以整個400k大約需要30分鐘,但它運行了將近4個小時。
隨着時間的推移,IMO可以減慢的唯一的事情就是填充Dataframe results
:我有什麼替代方法可以不使用.loc
並且速度更快?最後我仍然需要相同的數據框。
我也有興趣解釋爲什麼loc
在大型數據框上太慢了。
你有沒有想過使用pandas'迭代器之一(例如'iterrows()')遍歷您行並使用'應用'用你的閱讀器功能創建一個包含所有地理數據的字符串的新列?然後您可以拆分字符串爲所有地理數據創建單獨的列。不知道這是否會更快,但是在迭代數據框時,通常使用類似「iterrows()」的最佳實踐。 – Khris
我以前在for循環中使用'loc'的速度非常慢,我也遇到類似的問題。我發現我可以通過生成新列的數據作爲單獨的列表來避開這個問題,然後以這種形式重新分配它。這需要更多的代碼行,並且有點醜陋,但是性能比'loc'好得多。如果你能應用這個,可能值得考慮。 – oliversm
@oliversm你能詳細說明一下嗎?我真的不明白你的伎倆。 – CoMartel