【问题标题】:Faster solution for groupby and aggregate in PandasPandas 中 groupby 和聚合的更快解决方案
【发布时间】:2021-10-23 21:15:42
【问题描述】:

我有一个看起来像这样的数据框:

df = pd.DataFrame.from_dict({"id": [1,1,1,2,3,3], "s1": [4,np.nan,np.nan,1,1,5], "s2": [14,np.nan,19,np.nan,18,19]})

    id  s1  s2
0   1   4.0 14.0
1   1   NaN NaN
2   1   NaN 19.0
3   2   1.0 NaN
4   3   1.0 18.0
5   3   5.0 19.0

我的目标是将它转换成这样的结果

    s1          s2
id      
1   [4.0]       [14.0, 19.0]
2   [1.0]       [0]
3   [1.0, 5.0]  [18.0, 19.0]

这意味着我想按字段“id”进行分组,将所有其他列聚合到一个列表中(如果该组合的值为 NaN,则作为后备创建一个为零的列表)

我目前的纯 Pandas 方法对于较大的数据帧(> 100k 行和 ~100 列)非常慢。

def _aggregate_listwise(x):
    return list(x.dropna()) if not x.isnull().all() else [0]

df.groupby("id").agg(lambda x: _aggregate_listwise(x))

有没有一种不错的 Pythonic 方式来加快我的解决方案速度?谢谢你的建议!

【问题讨论】:

  • 可能微不足道,但你为什么将这个完美的函数包装在 lambda 中而不是 agg(_aggregate_listwise)
  • 是的,我认为这只是一点点帮助;)
  • 做一个乐观主义者怎么样agg(lambda x: list(x.dropna()) or [0])

标签: python pandas performance group-by aggregate


【解决方案1】:

类似于stack 然后unstack,但是对于对象列 agg,运行时间总是比平时长。

out = df.set_index('id').stack().groupby(level=[0,1]).agg(list).unstack(fill_value=[0])
Out[617]: 
            s1            s2
id                          
1        [4.0]  [14.0, 19.0]
2        [1.0]           [0]
3   [1.0, 5.0]  [18.0, 19.0]

【讨论】:

  • 非常感谢!提速5-10倍。堆栈/取消堆栈的好主意
猜你喜欢
  • 2022-01-26
  • 2013-05-27
  • 1970-01-01
  • 2021-11-10
  • 1970-01-01
  • 2019-01-29
  • 2018-09-29
  • 2020-01-28
  • 2021-11-01
相关资源
最近更新 更多