Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/277.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 加速dataframe.loc()_Python_Pandas_Geoip - Fatal编程技术网

Python 加速dataframe.loc()

Python 加速dataframe.loc(),python,pandas,geoip,Python,Pandas,Geoip,我有一个大约400k IP(存储在熊猫数据帧df_IP中)的列表,可以使用maxming geoIP数据库进行地理定位。我使用城市版本,检索城市、纬度、经度和县代码(法国的部门),因为有些城市有相同的名称,但在非常不同的地方 这是我的工作代码: import geoip2.database import pandas as pd reader = geoip2.database.Reader('path/to/GeoLite2-City.mmdb') results = pd.DataFram

我有一个大约400k IP(存储在熊猫数据帧df_IP中)的列表,可以使用maxming geoIP数据库进行地理定位。我使用城市版本,检索城市、纬度、经度和县代码(法国的部门),因为有些城市有相同的名称,但在非常不同的地方

这是我的工作代码:

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唯一能随时间变慢的事情是数据帧的填充
结果
:我有哪些不使用
.loc
的替代方案可以更快?最后我仍然需要相同的数据帧


我还想解释一下为什么
loc
在大型数据帧上速度如此之慢。

我也遇到了同样的问题,正如@oliversm建议的那样,我创建了一个列表,然后将其添加到原始数据集中。 下面是代码的样子:


我面临着一个类似的情况,因为loc导致我的运行时崩溃。经过多次修改,我找到了一个简单的解决方案,速度非常快。 使用set_值代替loc

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

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

self.data.set_value(45,'Label,'NA')
这将第二行的列“Label”的值设置为NA

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


您是否考虑过使用pandas'迭代器之一(例如,
iterrows()
)对您的行进行迭代,并使用
apply
和您的reader函数创建一个包含所有地理数据的字符串的新列?然后可以拆分字符串,为所有地理数据创建单独的列。不确定这是否会更快,但当在数据帧上迭代时,通常最好使用
iterrows()
之类的东西。我过去也遇到过类似的问题,在for循环中使用
loc
非常慢。我发现我可以通过将新列的数据作为一个单独的列表生成,然后以这种形式重新分配它来避免这个问题。这需要更多的代码行,有点难看,但性能比
loc
好得多。如果你能应用这个,也许值得考虑。@oliversm你能详细说明一下吗?我真的不明白你的把戏。@Khris,不,我从来没有使用过iterrows,我会试试IPs的独特性吗?
Index  'A'  'B' 'Label'
23      0    1    Y
45      3    2    N

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