Python Pandas - 带有 apply() 和 rolling() 的 groupby() 非常慢

Posted

技术标签:

【中文标题】Python Pandas - 带有 apply() 和 rolling() 的 groupby() 非常慢【英文标题】:Python Pandas - groupby() with apply() & rolling() very slow 【发布时间】:2020-03-19 11:45:56 【问题描述】:

首先,我对 Python 和 Pandas 还很陌生,所以请耐心等待并尽可能简单地回答。此外,如果您能详细说明与我的示例中的代码不同的任何代码,或者为我提供一个易于理解的可靠参考,我将不胜感激。

我有一个数据框 (df1) 包含 60 多列和 80 万行(并且还在增长)的 6000 多个地点的月度数据。我正在尝试根据位置许可证号 ('lic_num', int), 月份 ('mo_yr', date )。我已经使用 apply() 成功地做到了这一点。问题是 apply() 感觉非常慢,需要 10 分钟。这不是这个项目的主要问题,因为这不会是需要按需运行的东西,但我希望在我需要一个项目更快执行的情况下更有效地编写与此类似的代码。这是数据框 (df1) 的示例以及我用来实现结果的代码

lic_num      mo_yr        ap         aw       fi
120700142 2013-03-01  228214.3  206273.53  61393.0
120700142 2013-04-01  256239.4  235296.96  64228.0
120700142 2013-05-01  247725.3  227165.09  74978.0
120700142 2013-06-01  229776.8  211765.55  64559.0
120700142 2013-07-01  229036.2  210963.06  58132.0

df1_col_list = df1.columns.tolist()

for col in df1_col_list[2:5]:
    df1[col+'_3mo'] = df1.groupby('lic_num', as_index=False).apply(
    lambda x: x.rolling(3, on='mo_yr', min_periods=1)[col].mean()).reset_index(level=0, drop=True)

lic_num      mo_yr        ap         aw       fi         ap_3mo         aw_3mo        fi_3mo
120700142 2013-03-01  228214.3  206273.53  61393.0  228214.300000  206273.530000  61393.000000
120700142 2013-04-01  256239.4  235296.96  64228.0  242226.850000  220785.245000  62810.500000
120700142 2013-05-01  247725.3  227165.09  74978.0  244059.666667  222911.860000  66866.333333
120700142 2013-06-01  229776.8  211765.55  64559.0  244580.500000  224742.533333  67921.666667
120700142 2013-07-01  229036.2  210963.06  58132.0  235512.766667  216631.233333  65889.666667

【问题讨论】:

apply 和显式迭代应该是 Pandas 的最后手段。 【参考方案1】:

如果apply 很慢,我们尽量不要使用它。以下是有关apply 速度慢的原因的更多信息When should I ever want to use pandas apply() in my code?

s=df.groupby('lic_num', as_index=False).\
       rolling(3, on='mo_yr', min_periods=1).\       
          mean().iloc[:,2:5].\
             add_suffix('_3mo').reset_index(drop=True,level=0)

df=pd.concat([df,s],axis=1)

【讨论】:

谢谢。我很欣赏快速反应。一旦我回到家,我会尝试并更新。再次感谢。 尝试了建议的解决方案并收到以下错误。 “NotImplementedError:此 dtype datetime64[ns] 的滚动操作未实现” @JackValadez 我这边没有错误,你能检查一下你的熊猫版本吗? 好的。该代码正在处理我最初应用的示例数据帧,但是当尝试在更大的数据帧上使用它时,我遇到了错误。去深入研究,看看我能找到什么。谢谢。

以上是关于Python Pandas - 带有 apply() 和 rolling() 的 groupby() 非常慢的主要内容,如果未能解决你的问题,请参考以下文章

使用带有参数的 Pandas groupby() + apply()

Python Pandas:.apply 需要永远吗?

Python pandas.DataFrame.apply函数方法的使用

在apply函数pandas python中包含组名

Python Pandas:“numpy.ndarray”对象没有属性“apply”

Python pandas:我们可以避免在 groupby/apply 这种情况下应用吗?