【问题标题】:Pandas Groupby + Agg to List Very SlowPandas Groupby + Agg 上架速度非常慢
【发布时间】:2021-12-04 09:50:54
【问题描述】:

我有一个包含 200,000 行的 DataFrame,由以下代码生成:

In [5]: def create_df():
   ...:     df = {}
   ...:     for col_name in ['a', 'b', 'c', 'd', 'e', 'f']:
   ...:         df[col_name] = np.tile(list(range(100000)), 2)
   ...:     return pd.DataFrame(df)

我正在尝试执行一些需要 groupby 的下游应用程序,然后将 groupby 行聚合到列表中,如下所示:

In [7]: df.groupby(['a', 'b', 'c', 'd']).agg(list)
Out[7]: 
                                      e               f
a     b     c     d                                    
0     0     0     0              [0, 0]          [0, 0]
1     1     1     1              [1, 1]          [1, 1]
2     2     2     2              [2, 2]          [2, 2]
3     3     3     3              [3, 3]          [3, 3]
4     4     4     4              [4, 4]          [4, 4]
...                                 ...             ...
99995 99995 99995 99995  [99995, 99995]  [99995, 99995]
99996 99996 99996 99996  [99996, 99996]  [99996, 99996]
99997 99997 99997 99997  [99997, 99997]  [99997, 99997]
99998 99998 99998 99998  [99998, 99998]  [99998, 99998]
99999 99999 99999 99999  [99999, 99999]  [99999, 99999]

但是,鉴于 DataFrame 只有 200,000 行,此操作比预期慢得多(平均约 15 秒):

In [8]: %timeit df.groupby(['a', 'b', 'c', 'd']).agg(list)
14.7 s ± 1.13 s per loop (mean ± std. dev. of 7 runs, 1 loop each)

相比之下,对 groupby 应用计数平均只需要约 45 毫秒,这表明减速似乎只是按列表聚合:

In [10]: %timeit df.groupby(['a', 'b', 'c', 'd']).agg('count')
44.7 ms ± 2.23 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

我可以在这里做些什么来加快按列表进行聚合的操作?现在这是我代码中的真正瓶颈。

【问题讨论】:

  • 你真的需要列表吗?不建议将它们用作 DataFrame 的内容
  • 你愿意使用元组吗? df.groupby(['a', 'b', 'c', 'd']).agg(tuple)?它在我的环境中提供了 2 倍的加速
  • df[["a","b"]].values.tolist() 快速列表。在您目前的情况下,不需要groupby
  • @DaniMesejo 在我的用例中给了我 5 倍的加速,谢谢!
  • 您介意我发帖作为答案吗?

标签: python pandas aggregate-functions


【解决方案1】:

试试df.groupby(['a', 'b', 'c', 'd']).agg(lambda x: x.tolist())

【讨论】:

  • 不,这和 OP 中的代码一样慢 :(
【解决方案2】:

一种方法是使用元组而不是列表:

df.groupby(['a', 'b', 'c', 'd']).agg(tuple)

这在我的环境中提高了 2 倍

df = create_df()
%timeit df.groupby(['a', 'b', 'c', 'd']).agg(tuple)
2.38 s ± 52.1 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%timeit df.groupby(['a', 'b', 'c', 'd']).agg(list)
5.41 s ± 28.7 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

【讨论】:

    猜你喜欢
    • 2019-04-10
    • 1970-01-01
    • 2016-05-21
    • 1970-01-01
    • 2012-02-25
    • 2020-03-19
    • 1970-01-01
    • 2020-03-03
    • 2016-10-10
    相关资源
    最近更新 更多