首页 > 编程问答 >Pandas:递归的性能优化

Pandas:递归的性能优化

时间:2024-07-23 13:15:08浏览次数:14  
标签:python pandas numpy

我有一个代码,看起来像

for index, row in data.iterrows():
   data.loc[index, "myCol"] = someFunc(data.loc[index-1, "myCol")

该代码正在使用递归,因此我无法对其进行矢量化,因为在许多与 iterrows 性能相关的问题中都建议使用递归。

我在性能方面优化它的最佳方法是什么?


虽然 Pandas 的 iterrows 方法为循环遍历 DataFrame 提供了一种直观的方式,但当涉及到性能时,它并不是最有效的方法,尤其是在大型数据集上。你的代码似乎递归地更新“myCol”列,其中每个值都取决于其前一个值。这种模式确实限制了矢量化(Pandas 中基于数组的操作,速度要快得多)的机会。

让我们探讨一下在保持递归行为的同时优化代码的一些策略:

  1. 使用 shift() 进行高效滞后计算:

Pandas 的 shift() 方法非常适合访问 DataFrame 中先前行的值,这使其成为递归模式的理想选择。你可以通过以下方式重构代码以利用它:

python data['myCol_shifted'] = data['myCol'].shift(1) data['myCol'] = data.apply(lambda row: someFunc(row['myCol_shifted']) if not pd.isnull(row['myCol_shifted']) else row['myCol'], axis=1) data = data.drop('myCol_shifted', axis=1)

在这个解决方案中,我们首先创建 myCol 的移位副本。然后,我们使用 apply 和 lambda 函数,如果存在先前值(非空),则有条件地应用 someFunc 。这确保了递归计算的正确性。最后,我们删除辅助移位列。

  1. 使用 itertuples() 进行更快的行迭代(如果 shift() 不适用):

如果由于 someFunc 的复杂性或你的数据的特定特征而导致 shift() 方法不可行,那么与 iterrows 相比, itertuples() 提供了一个更快的 DataFrame 迭代选项。 itertuples 以元组的形式迭代 DataFrame 的行,提供对列值的更快访问。

python for i in range(1, len(data)): data.loc[i, "myCol"] = someFunc(data.loc[i-1, "myCol"])

  1. 使用 Numba JIT 编译(用于潜在的显著加速):

如果你的函数 someFunc 可以使用 Numba 进行编译,你就可以获得显著的性能提升,尤其是对于大型数据集。Numba 可以对 Python 代码进行 JIT 编译,包括循环和递归函数,使它们能够以接近本机的速度运行。

```python from numba import jit

@jit(nopython=True) def someFunc(x): # someFunc 的实现 return x

for i in range(1, len(data)): data.loc[i, "myCol"] = someFunc(data.loc[i-1, "myCol"]) ```

使用 @jit(nopython=True) 装饰器,Numba 尝试在不依赖 Python 解释器的情况下编译该函数。这对于数值运算密集型任务非常有效。

  1. 探索 Cython 实现(用于高级优化):

对于性能至关重要的场景,考虑使用 Cython 实现你的递归逻辑。Cython 允许你将 Python 代码与 C 数据类型混合,从而实现更接近本机代码的性能。

请记住,最佳方法取决于你的数据的具体特征、 someFunc 的复杂性以及你的性能需求。对这些选项进行基准测试以确定哪种方法最适合你的用例非常重要。

标签:python,pandas,numpy
From: 78781615

相关文章

  • Python 类型提示和 linter
    我一直在向我们的python项目添加静态类型检查,例如像这样:fromtypingimportListfromsomethingimportMyOtherClassclassMyClass:def__init__(self)->None:self.some_var=None#type:List[MyOtherClass]但是,现在我们使用的linter(flake8和......
  • eclipse如何写python程序
    本文主要介绍在Windows系统环境下,搭建能在Eclipse中运行python程序的环境。一、Eclipse下载与安装:Eclipse是写JAVA的IDE,下载地址为:http://www.eclipse.org/downloads/下载安装,网上教程很多,不赘述。二、pydev插件下载与安装:启动Eclipse,点击Help—>EclipseMarketplace......
  • 运行 python 3 代码时出现 python 2 语法错误
    我有一个如下所示的类classExperimentResult(BaseDataObject):def__init__(self,result_type:str,data:dict,references:list):super().__init__()self.type=result_typeself.references=referencesself.data=data......
  • 如何让 python 类型检查器知道它应该返回其类的新实例?
    我想使用classmethod返回当前类的新实例,并且我尝试了如下代码,但它引发了NameError('name'T'isnotDefined')PutthecodeT=TypeVar('T',bound=A)on|||以上也不起作用。classA有什么好主意来处理它吗?Isthereanygoodideatohandleit?......
  • 由于循环依赖而导致的Python注释错误
    我有两个相互依赖的类,并且无需注释即可正常工作。不幸的是,当我尝试注释返回值时,它会导致预期循环依赖错误。Network.pydefprocessors(self)->List[Processor]:#implementationProcessor.pydefnetwork(self)->Network:......
  • 如何在python中发送带有请求的“multipart/form-data”?
    如何在Python中使用multipart/form-data发送requests?如何发送文件,我明白,但是如何通过这种方法发送表单数据无法理解。可以使用Python中的requests库来发送multipart/form-data请求。说得对,requests库可以轻松发送文件,并且发......
  • 我安装了哪个版本的 Python?
    我必须在Windows服务器上运行Python脚本。我如何知道我拥有哪个版本的Python,这真的很重要吗?我正在考虑更新到最新版本的Python。确定在Windows服务器上安装的Python版本至关重要,因为它可以确定脚本的兼容性和可用库。以下是检查方法:使用命令提......
  • @classmethod 在 Python 的类之外做什么?
    在下面的代码中,如果存在@classmethod注释,则允许内部defnew()代替目标的__new__()--但该类会传递两次。如果@classmethod被删除,那么我们会收到类似“”的错误。@classmethod这里在做什么,有没有办法不用它?(我的动机是清晰的:我不理......
  • 三种语言实现快速选择(C++/Python/Java)
    题目给定一个长度为......
  • 如何让SublimeText支持Python 3的注释?
    我测试了SublimeText2和3,两者都有错误:如果您测试此代码,您会注意到:之后的所有代码都不会正确突出显示语法。deffoo(a,b)->str:#Nothinggetsproperlycoloredfromhere#Abunchofcode…return"bar"我发现了一些链接,解释了如何......