【问题标题】:Speeding up pandas groupby aggregation加速 pandas groupby 聚合
【发布时间】:2021-09-19 22:10:00
【问题描述】:

我有一个如下所示的数据集:

id     count
A.     2
A.     10
B.     3
B.     13
B.     11
C.     2
C.     3

我需要为每个 ID 汇总“计数”值的总和和平均值。使用熊猫,我正在做这样的事情:

stats = df.groupby('id').agg({'agg': ['sum', 'mean']})

我尝试使用 numpy 数组对此进行优化:

counts = df['count'].values
ids = df['id'].values
all_ids = df['id'].unique()
stats = [(i, np.mean(df[ids==i]), np.sum(df[ids==i])) for i in all_ids]

但是,这最终会比相应的 pandas 实现花费更多的时间。有没有办法加快速度(也许使用一些 numpy 功能?)

【问题讨论】:

  • 数据框是否已经按 ID 排序?
  • 您的意思是df.groupby('id').agg(['sum', 'mean']) - 您当前的语法没有意义,因为您没有标记为'agg' 的列?您还可以提供更多关于为什么内置性能没有切入的信息吗?这些操作开始时通常非常快,不是最佳的,但要爬上高山才能挤出一点额外的东西。但有可能您正在对 str 列求和(可能很慢),或者您有一个缺少值的分类,当它最终尝试重新索引时确实会减慢速度。

标签: python pandas numpy pandas-groupby aggregate


【解决方案1】:

仅当您的数据框按 id 排序时

# a = df.sort_values('id').values
a = df.values
a = a[a[:, 0].argsort()]
groups, indexes = np.unique(a[:, 0], return_index=True)
values = np.split(a[:, 1], indexes[1:])
r = np.array([(np.mean(v), np.sum(v)) for v in values])

我觉得你可以用np.view排序但是我不知道怎么用。

>>> groups
array(['A.', 'B.', 'C.'], dtype=object)

>>> indexes
array([0, 2, 5])

>>> values
[array([2, 10], dtype=object),
 array([3, 13, 11], dtype=object),
 array([2, 3], dtype=object)]

>>> r
array([[ 6. , 12. ],
       [ 9. , 27. ],
       [ 2.5,  5. ]])

性能

对于 1,000,000 个值和 1000 个不同的组

id_ = np.random.randint(1, 1001, 1000000)
count = np.random.randint(1, 60, 1000000)
df = pd.DataFrame({'id': id_, 'count': count})

%timeit np.array([(np.mean(v), np.sum(v)) for v in values])
18 ms ± 465 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-11-23
    • 2022-01-21
    • 2019-08-10
    • 2017-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-29
    相关资源
    最近更新 更多