Python 如何在for循环中提高处理数据帧的CPU利用率?

Python 如何在for循环中提高处理数据帧的CPU利用率?,python,dataframe,for-loop,optimization,geocoding,Python,Dataframe,For Loop,Optimization,Geocoding,我有一个大约200000个地址的数据集,我想对这些地址进行地理编码(即,查找这些地址的纬度和经度)。我的(简化)代码如下所示: import pandas as pd import numpy as np df = pd.read_csv('dataset.csv') Latitudes = np.zeros(len(df)) Longitudes = np.zeros(len(df)) def geocode_address(address): ### The logic for

我有一个大约200000个地址的数据集,我想对这些地址进行地理编码(即,查找这些地址的纬度和经度)。我的(简化)代码如下所示:

import pandas as pd
import numpy as np

df = pd.read_csv('dataset.csv')
Latitudes = np.zeros(len(df))
Longitudes = np.zeros(len(df))

def geocode_address(address):
    ### The logic for geocoding an address
    ### and return its latitude and longitude

for i in range(len(df)):
    try:
        lat, lon = geocode_address(df.Address[i])
    except:
        lat = lon = ''
    Latitudes[i] = lat
    Longitudes[i] = lon

问题是每一行(地址)需要大约1-1.3秒的时间来进行地理编码,因此该代码至少需要几天的时间来完成整个数据集的运行。我在Windows10的jupyter笔记本上运行这个。当我查看任务管理器时,我看到进程
jupyter.exe
只占用了0.3-0.7%的CPU我认为这是出人意料的低。我看到的是错误的流程吗?如果没有,我如何将此代码的CPU利用率至少提高到50%,这样代码就可以在几分钟或几小时内完成运行,而不是几天?

你找错了方向。您的代码不受CPU限制,而是受IO限制(没有密集的计算,大部分时间都花在HTTP请求上)


这些问题的标准解决方案是并行化(您可能想看看
多处理
模块),而且它本身很容易在这里实现,因为-但是您仍然需要处理地理编码API速率限制。

您在错误的树上吠叫。您的代码不受CPU限制,而是受IO限制(没有密集的计算,大部分时间都花在HTTP请求上)


此类问题的标准解决方案是并行化(您可能想看看
多处理
模块),它本身很容易在这里实现,因为-但您仍然需要处理地理编码API速率限制。

我根据Bruno的建议解决了这个问题,通过将数据划分为10个子集,每个子集包含20k行。然后我在每个分区上用相同的代码运行了10台jupyter笔记本电脑。这基本上是“石器时代的并行处理”,但它确实以一种简单的方式解决了这个问题——整个工作大约在5小时内完成

但要记住的关键是要注意每个笔记本占用了多少CPU——在我的例子中,大约是1%。因此,理论上,我可以把数据分成,比如说,50个部分,整个任务大约在一个小时内完成。但是,如果每个笔记本占用(比如)10%的CPU,那么我最多会将数据划分为6-7个部分,因为我希望为其他应用程序和进程保留至少30-40%的CPU


我很想知道是否有一种方法可以自动化这个过程——即,找到分区的最大数量,这样当在每个分区上运行同一个笔记本时,CPU的总使用量就不会超过指定的阈值。然后,当然,对数据进行分区并在每个数据上运行代码。

我根据Bruno的建议解决了这个问题,将数据分为10个子集,每个子集中有20k行。然后我在每个分区上用相同的代码运行了10台jupyter笔记本电脑。这基本上是“石器时代的并行处理”,但它确实以一种简单的方式解决了这个问题——整个工作大约在5小时内完成

但要记住的关键是要注意每个笔记本占用了多少CPU——在我的例子中,大约是1%。因此,理论上,我可以把数据分成,比如说,50个部分,整个任务大约在一个小时内完成。但是,如果每个笔记本占用(比如)10%的CPU,那么我最多会将数据划分为6-7个部分,因为我希望为其他应用程序和进程保留至少30-40%的CPU


我很想知道是否有一种方法可以自动化这个过程——即,找到分区的最大数量,这样当在每个分区上运行同一个笔记本时,CPU的总使用量就不会超过指定的阈值。然后,当然,对数据进行分区,并在每个数据上运行代码。

是否强烈需要循环?为什么不
apply
?@Fourier我实际上是在一个文件中保存(附加)每1000条记录的结果,这就是为什么我使用for循环。但我这样做的原因是,如果内核死机(或出现任何错误),我可以得到目前为止的结果。但是,如果使用
apply
可以在几分钟内完成,那么我愿意这样做。然而,我不认为这会起作用,因为我正在使用hereapi进行地理编码,我认为他们会在空闲层(我正在使用)设置一些速度限制。更不用说每月允许的免费地理编码的数量限制了。你需要检查python.exe而不是jupyer.exe,你能把你的完整代码放在这里,这样我们就可以看看它是否可以改进(for loop可能是最慢的方式)我看不出使用for loop和此处API的限制之间有任何关系。。。无论您的本地计算机是快还是慢,限制都是固定的。那么,您的本地计算机速度最好更快。@mayelsgc用我的完整代码更新了问题的详细信息。是否有强烈的循环需求?为什么不
apply
?@Fourier我实际上是在一个文件中保存(附加)每1000条记录的结果,这就是为什么我使用for循环。但我这样做的原因是,如果内核死机(或出现任何错误),我可以得到目前为止的结果。但是,如果使用
apply
可以在几分钟内完成,那么我愿意这样做。然而,我不认为这会起作用,因为我正在使用hereapi进行地理编码,我认为他们会在空闲层(我正在使用)设置一些速度限制。更不用说每月允许的免费地理编码的数量限制了。你需要检查python.exe而不是jupyer.exe,你能把你的完整代码放进去,这样我们就可以看看它是否可以改进(因为循环可能是最慢的方式)我看不出使用