Pandas DataFrame-Aggregate对dtype=='category'列的聚合导致性能缓慢[英] Pandas DataFrame - Aggregate on column whos dtype=='category' leads to slow performance

本文是小编为大家收集整理的关于Pandas DataFrame-Aggregate对dtype=='category'列的聚合导致性能缓慢的处理方法,想解了Pandas DataFrame-Aggregate对dtype=='category'列的聚合导致性能缓慢的问题怎么解决?Pandas DataFrame-Aggregate对dtype=='category'列的聚合导致性能缓慢问题的解决办法?那么可以参考本文帮助大家快速定位并解决问题。

问题描述

我使用具有高内存使用量的大数据框,我读到,如果我更改重复值列上的dtype,我可以节省大量内存.

我尝试了它,实际上它使记忆使用量减少了25%,但后来我撞到了我无法理解的性能慢下.

我在dtype"类别"列上进行集体聚合,在我更改dtype之前,大约需要1秒钟,然后更改后花费了大约1分钟.

此代码以2:

的速度证明了性能降解.
import pandas as pd
import random

animals = ['Dog', 'Cat']
days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday','Saturday']

columns_dict = {'animals': [],
                'days': []}

for i in range(1000000):
    columns_dict['animals'].append(animals[random.randint(0, len(animals)-1)])
    columns_dict['days'].append(days[random.randint(0, len(days)-1)])

# df without 'category' dtype
df = pd.DataFrame(columns_dict)

df.info(memory_usage='deep') # will result in memory usage of 95.5 MB

%timeit -n100 df.groupby('days').agg({'animals': 'first'})
# will result in: 100 loops, best of 3: 54.2 ms per loop

# df with 'category' dtype
df2 = df.copy()
df2['animals'] = df2['animals'].astype('category')

df2.info(memory_usage='deep') # will result in memory usage of 50.7 MB

%timeit -n100 df2.groupby('days').agg({'animals': 'first'})
# will result in: 100 loops, best of 3: 111 ms per loop

我试图理解的是,这种缓慢的原因是什么,如果有一种克服的方法.

谢谢!

推荐答案

我不确定这种放缓的来源,但是一个解决方法是直接存储类别代码:

df3 = df.copy()
animals = pd.Categorical(df['animals'])
df3['animals'] = animals.codes
df3.groupby('days').agg({'animals': 'first'}).apply(lambda code: animals.categories[code])

这不是最干净的解决方案,因为它需要外部元数据,但是它既可以达到内存效率和您想要的计算速度.挖掘熊猫在内部进行的事情会很有趣,这会导致分类的这种放缓.


编辑:我跟踪为什么会发生这种情况...作为first()聚合的一部分,pandas call 上的调用np.asarray().在分类列的情况下,最终将列转换回非类别,导致不必要的开销.解决此问题将是Pandas软件包的有用贡献!

本文地址:https://www.itbaoku.cn/post/1727991.html