2017-02-16 76 views
0

我有一個約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在大型數據框上太慢了。

+0

你有沒有想過使用pandas'迭代器之一(例如'iterrows()')遍歷您行並使用'應用'用你的閱讀器功能創建一個包含所有地理數據的字符串的新列?然後您可以拆分字符串爲所有地理數據創建單獨的列。不知道這是否會更快,但是在迭代數據框時,通常使用類似「iterrows()」的最佳實踐。 – Khris

+0

我以前在for循環中使用'loc'的速度非常慢,我也遇到類似的問題。我發現我可以通過生成新列的數據作爲單獨的列表來避開這個問題,然後以這種形式重新分配它。這需要更多的代碼行,並且有點醜陋,但是性能比'loc'好得多。如果你能應用這個,可能值得考慮。 – oliversm

+0

@oliversm你能詳細說明一下嗎?我真的不明白你的伎倆。 – CoMartel

回答

0

我有同樣的問題,因爲@oliversm建議我創建一個列表,然後將其添加到原始數據集。 下面是代碼會是什麼樣子:

....

results_list=[] 

for i, IP in enumerate(df_IP["IP"]): 
    try : 
     response = reader.city(IP) 
    results_list.append(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) 

results_array=np.asarray(results_list) #list to array to add to the dataframe as a new column 

results['results_column']=pd.Series(results_array,index=results.index) 
0

我面臨着類似的情況作爲LOC是造成運行時炸燬了我。在擺弄了很多之後,我發現了一個超快的簡單解決方案。 使用set_value而不是loc。

這是一個示例代碼的樣子:您可以調整它爲您的用例。假設你的數據幀是這樣

Index 'A' 'B' 'Label' 
23  0 1 Y 
45  3 2 N 

self.data.set_value(45,'Label,'NA') 

這將設置欄「標籤」爲NA的價值,爲第二排。

更多SET_VALUE可以從下面的鏈接閱讀:

http://pandas.pydata.org/pandas-docs/version/0.17/generated/pandas.DataFrame.set_value.html