如何正确使用带有应用功能的熊猫 groupby 来解决副作用? (第一组申请两次)

Posted

技术标签:

【中文标题】如何正确使用带有应用功能的熊猫 groupby 来解决副作用? (第一组申请两次)【英文标题】:How to properly use pandas groupby with apply function for side effects? (First group applied twice) 【发布时间】:2019-03-13 15:54:36 【问题描述】:

我正在使用 pandas 对数据框中的某些列进行分组,并将自定义函数应用于这些组。应用函数利用副作用并作用于函数内的全局数据对象。

pandas、groupby 和 apply 的一个记录警告是,根据设计,它会在第一组上应用两次调用的函数来决定它是否可以采用快速或慢速代码路径。这记录在这里: http://pandas.pydata.org/pandas-docs/stable/groupby.html#flexible-apply

在这里演示:

In [144]: d = pd.DataFrame("a":["x", "y"], "b":[1,2])

In [145]: def identity(df):
   .....:     print(df)
   .....:     return df
   .....: 

In [146]: d.groupby("a").apply(identity)
   a  b
0  x  1
   a  b
0  x  1
   a  b
1  y  2
Out[146]: 
   a  b
0  x  1
1  y  2

在此处的其他一些 *** 帖子中提到:

Python pandas groupby object apply method duplicates first group

Is Pandas 0.16.1 groupby().apply() method applying function more than once to the same group?

此处在 GitHub 上提及:

https://github.com/pandas-dev/pandas/issues/7739

https://github.com/pandas-dev/pandas/issues/19167

这意味着我的副作用在第一组中被调用了两次,并导致了不必要的更改。

我的问题是如何使用 pandas、groupby 和 apply 而不会在第一组(或任何组)上应用两次副作用,并保证每个组只调用一次?强>

我想在 DataFrame 的顶部创建一个虚拟/假组,但我想将我的问题扩展到 *** 社区,以获得更好的解决方案并造福他人。

感谢您的帮助。

编辑:

根据 cmets 的要求,提供有关自定义功能和副作用的更多详细信息。

使用具有副作用的自定义函数会在函数的开头和结尾使用全局字典。它使用键检索数据并将这些值应用于行,在函数结束时,更新的值会更新到全局字典中,以便新值反映在下一次迭代中。

将 groupby 与 apply 一起使用的主要原因是,它是我在有效迭代数据帧 groupby 对象时找到的最快的应用程序。我还研究了简单的迭代和列表理解。

【问题讨论】:

你能提供一个用例或示例“副作用”吗?它将为您的问题提供更多背景信息,并帮助我们了解为什么双重调用是一个问题。 已经在 doc pandas.pydata.org/pandas-docs/stable/… 中提到,也请查看 github github.com/pandas-dev/pandas/issues/7739 @jpp 我不认为他可以在这里得到答案,因为这个问题与 pandas api 建设有关。 【参考方案1】:

从 2019 年 7 月 18 日 Groupby.apply 发布的 pandas 版本 0.25.0 开始,对这个问题的跟进只对第一组进行一次评估。升级到此版本可能是解决此问题的最直接方法。

在这里发布信息:https://pandas.pydata.org/pandas-docs/stable/whatsnew/v0.25.0.html

【讨论】:

以上是关于如何正确使用带有应用功能的熊猫 groupby 来解决副作用? (第一组申请两次)的主要内容,如果未能解决你的问题,请参考以下文章

如何调试熊猫 groupby 应用功能

带有groupby的熊猫数据框滚动窗口

如何在熊猫中按对象分组应用滚动功能

熊猫如何将函数应用于 groupby().first()

熊猫应用功能 - 将每一行与整列进行比较

带有应用功能的熊猫空值检查