如何更快地生成基于组的列?

时间:2014-04-14 08:50:04

标签: python pandas

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

      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行的数据框中,上面的代码在我的电脑上占用的时间超过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 sec,而method 2大约需14 sec。但是,groupby似乎没有用于生成group size, group max, group mean等列的属性。还有其他方法可以改善此处的效果吗?

感谢任何帮助。

1 个答案:

答案 0 :(得分: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

这会按组数而不是行数进行缩放

等待某人实施。它并不困难,并且是一个很好的第一次拉动请求。