在大型Pandas DataFrame上避免GroupBy的内存问题

时间:2018-04-26 20:18:31

标签: python pandas dataframe memory dask

更新

pandas df是这样创建的:

df = pd.read_sql(query, engine)
encoded = pd.get_dummies(df, columns=['account'])

从这个df创建一个dask df如下所示:

df = dd.from_pandas(encoded, 50)

使用dask执行操作导致没有可见的进展(使用dask诊断检查):

result = df.groupby('journal_entry').max().reset_index().compute()

原始

我有一个大型的pandas df,有2.7M行和4,000列。除了四列之外的所有列都是dint uint8。 uint8列只保存值1或0.我试图在df:

上执行此操作
result = df.groupby('id').max().reset_index()

可以预见,此操作会立即返回内存错误。我最初的想法是水平和垂直地对df进行分块。但是,这会造成混乱的情况,因为.max()需要跨所有uint8列执行,而不仅仅是一对列。另外,像这样将df分块的速度仍然非常慢。我的机器上有32 GB的RAM。

什么策略可以缓解内存问题?

3 个答案:

答案 0 :(得分:2)

您可以使用dask.dataframe执行此任务

table1

您需要做的就是将import dask.dataframe as dd df = dd.from_pandas(df) result = df.groupby('id').max().reset_index().compute() 转换为pandas.DataFrame。 Dask是一个python核外并行化框架,提供各种并行化容器类型,其中一个是数据帧。它允许您执行最常见的pandas.DataFrame操作并行和/或分布式数据太大而无法放入内存中。 dask的核心是一组调度程序和用于构建计算图的API,因此我们必须在最后调用.compute()以便实际进行任何计算。该库易于安装,因为它大部分是用纯Python编写的。

答案 1 :(得分:1)

作为一个想法,我会说,分割数据列明智地说四次,并使用每个子集的id来执行操作然后重新合并

答案 2 :(得分:1)

如果数据中有任何分类列(而不是将类别存储为对象列或字符串),请确保在groupby命令中使用了observed = True选项。这确保了它仅创建存在条目的行,例如每个customer_id,order_id组合仅一行,而不是创建n_custs * n_orders行!

我只是对一个2600万行数据集进行了一个groupby-sum,从来没有超过7GB的RAM。在添加observed = True选项之前,它先升至62GB,然后耗尽。