【问题标题】:Create new dataframe with condtion per groupby in pandas在 Pandas 中为每个 groupby 创建具有条件的新数据框
【发布时间】:2020-07-30 12:26:00
【问题描述】:

我正在尝试根据每个 groupby 的条件创建新的数据框。 假设,我有名称、标志和月份的数据框。

import pandas as pd
import numpy as np

data = {'Name':['A', 'A', 'B', 'B'], 'Flag':[0, 1, 0, 1], 'Month':[1,2,1,2]}

df = pd.DataFrame(data)

need = df.loc[df['Flag'] == 0].groupby(['Name'], as_index = False)['Month'].min()

我的条件是找到每个名称的标志等于 0 的最小月份。

我使用.loc 来定义我的条件,它工作正常,但我发现它在应用 1000 万行时性能很差。

还有更有效的方法吗?

谢谢!

【问题讨论】:

  • 如果没有更好的解决方案,您可以将sort=False 传递给groupby 以使 if 更快。
  • 我认为dask 在这里应该有所帮助,因为数据量很大。
  • 你介意分享你运行它花了多长时间

标签: python pandas dataframe conditional-statements pandas-groupby


【解决方案1】:

昨天刚遇到同样的情况,我将 90 秒的过程缩短到大约 3 秒。因为速度是您关心的问题(就像我关心的那样),而不是只使用 Pandas 本身,我建议使用 NumbaNumPy。问题是您将不得不复习您的数据结构和类型,才能很好地掌握 Numba 对 JIT 的真正作用。但是,一旦你这样做了,它就会摇摆不定。

我建议找到一种方法将 DataFrame 中的每个值都设为整数。对于您的姓名列,请尝试使用唯一 ID。标志和月份看起来不错。

name_ids = []
for i, name in enumerate(np.unique(df["Name"])):
  name_ids.append({i: name})

然后,创建一个函数并以老式方式循环:

@njit
def really_fast_numba_loop(data):
  for row in data:
    # do stuff
  return data

new_df = really_fast_numba_loop(data)

第一次在文件中调用您的函数时,它的速度与在其他地方的速度大致相同,但在其他所有时间里,它都会快如闪电。所以,诀窍是在函数中放入什么和在其外部循环中放入什么之间找到平衡。

在任何一种情况下,当您处理完您的值后,将您的 name_ids 转换回字符串并将您的数据包装在 pd.DataFrame 中。

等等,瞧。你刚刚击败了 Pandas iterrows/itertuples。

如有问题请回复!

【讨论】:

  • 我认为aggregation of min 在 pandas 中是 cython 优化的,link,所以这里的 numba 应该更快?不确定。此外,您的代码不会聚合 min.
  • 首先,你摇滚。你不知道在我的职业生涯中我用了多少你的工作。万分感谢。其次,我同意你的看法,有很多方法可以通过深入研究来解决这个问题。在我遇到的情况下,我遇到了与 OP 相同的问题,并且通过上述方法,我最终击败了 Pandas。不过,这需要很多分析。它绝对不是pythonic。但是,它给了我我需要的结果,希望它能让 OP 一样。
  • 首先,我只想说,不确定在numba中这个操作是否更快。因此可以使用聚合 min 创建解决方案并在一些大型数据框中对其进行测试,例如10M 行、10k 组并进行比较?
  • 我认为这最终取决于 OP。您推荐了 Dask(好主意),另一个人推荐通过 sort=False,我认为这将使当前代码保持工作并提高速度,尽管我不知道多少以及它是否可以被 OP 接受。我的解决方案对我有用,我很满意。因此,我们有 3 个解决方案供 OP 尝试。让我们看看 OP 说了什么,然后从那里开始?我这么说是因为这个问题是主观的。 “我如何让这更快”可以通过多种方式完成,但可能不适合他们的项目。
  • 是的,我同意。但是您的解决方案只是pseodocode,它不聚合min。所以不能和OP代码比较。
猜你喜欢
  • 1970-01-01
  • 2021-06-11
  • 1970-01-01
  • 1970-01-01
  • 2022-01-23
  • 2021-04-06
  • 1970-01-01
  • 2022-08-17
  • 2017-01-17
相关资源
最近更新 更多