加速dataframe.loc()

2024-06-01 08:18:02 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个约400k IP的列表(存储在pandas数据框df iu IP中)以使用maxming geoIP数据库进行地理定位。我使用City版本,检索城市、栅格、经度和县代码(法国的department),因为有些城市的名称相同,但位于非常不同的地方。在

以下是我的工作代码:

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唯一可以减慢速度的是数据帧的填充results:我有什么替代方法不使用.loc,而且可以更快?我最后还是需要同样的数据帧。在

我还想解释一下为什么loc在大数据帧上运行如此慢。在


Tags: 数据代码importipcitypandasdfresponse
2条回答

我也遇到了同样的问题,正如@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)

我也面临着类似的情况,因为loc导致运行时崩溃。经过一番努力,我找到了一个简单的解决方案,它非常快。 使用set_value代替loc。在

这就是示例代码的外观:您可以根据您的用例对其进行调整。假设你的数据帧是这样的

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

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

这将把第二行的列“Label”的值设置为NA。在

有关set U值的更多信息,请访问以下链接:

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

相关问题 更多 >