【问题标题】:How to generate group based columns faster?如何更快地生成基于组的列?
【发布时间】:2014-04-14 08:50:03
【问题描述】:

我想为我的数据框创建一个基于 anther 列的列。例如,我有一个这样的数据框:

      Content        Date
ID                       
Bob  birthday  2010.03.01
Bob    school  2010.04.01
Tom  shopping  2010.02.01
Tom      work  2010.09.01
Tom   holiday  2010.10.01

我想生成一个等于ID 大小的列,因此生成的数据框如下所示:

      Content        Date  Size
ID                       
Bob  birthday  2010.03.01     2
Bob    school  2010.04.01     2
Tom  shopping  2010.02.01     3
Tom      work  2010.09.01     3 
Tom   holiday  2010.10.01     3

标准方式似乎使用groupbytransform。代码将完成工作:

df['Size'] = df['Date'].groupby(df.index).transform(np.size)

问题是,transform 运行速度非常慢。在具有大约40k 行的数据框中,上面的代码在我的PC 上占用的时间超过10 sec。我经常处理大于 100 万行的数据集,并且经常生成基于组的变量。

问题在于transform。例如,如果我使用

在同一数据帧上生成 cumcount
# method 1: use groupby attribute 'cumcount'
df['cumcount'] = df['Date'].groupby(df.index).cumcount()
# method 2: use 'transform'
df['cumcount'] = df['Date'].groupby(df.index).transform(lambda x: np.arange(0, len(x)))

method 1 大约需要 0.2 secmethod 2 再次需要大约 14 sec。不过groupby好像没有group size, group max, group mean等生成列的属性,这里有没有其他方法可以提高性能?

感谢任何帮助。

【问题讨论】:

  • df['cumcount'] = df['Date'].groupby(df.index).transform('count') 的表现如何?
  • @EdChum,谢谢。我刚刚测试了它。大约需要11 sec,类似于tranform(np.size)。我认为问题在于transform,而不是它调用的函数。
  • 我刚刚对您的示例数据进行了%timeit 并看到了相同的结果
  • 您是否尝试在您的 groupby 上执行多个聚合函数?您可以传递函数名称列表:pandas.pydata.org/pandas-docs/stable/…
  • @EdChum,不,我正在尝试生成一个包含统计信息的列,这正是文档中的transform 所做的:pandas.pydata.org/pandas-docs/stable/…,除了我对速度不满意。这可以在 STATA 中非常快地完成,我相信 python 也可以做得很好。

标签: python pandas


【解决方案1】:

在此处查看此问题:https://github.com/pydata/pandas/issues/6496

这些是等价的,但是第二个更快

In [41]: %timeit grp.transform(np.size)
1 loops, best of 3: 442 ms per loop

In [40]: %timeit pd.concat([ Series([r]*len(grp.groups[i])) for i, r in enumerate(grp.size().values) ],ignore_index=True)
10 loops, best of 3: 135 ms per loop

这取决于组数而不是行数

等待某人实施。这并不难,并且会是一个很好的第一个拉取请求。

【讨论】:

  • 谢谢!链接页面pd.Series(np.repeat(grp.mean().values, grp.count().values)) 中的最终结果效果很好。事实上,使用 grp.size().values 可以进一步提高速度(在我的测试中时间减少了一半以上)。
  • 事实上,在我的例子中(生成组大小列),使用group.count().values(这里两次)需要4秒,而使用group.size().values需要0.07秒。也许您可以将这一点添加到该讨论线程中?
  • 目前一个关于计数/大小的开放问题应该是大小的同义词
  • 是的,但是尺寸比计数似乎有相当大的速度优势。
猜你喜欢
  • 2022-06-10
  • 2023-01-17
  • 2011-03-21
  • 1970-01-01
  • 2021-08-04
  • 1970-01-01
  • 2020-06-07
  • 2010-10-20
  • 1970-01-01
相关资源
最近更新 更多